Categories
不学无术

1046. Shortest Distance (20)

时间限制:100ms
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (in [3, 105]), followed by N integer distances D1 D2 … DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (<=104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 107.
Output Specification:
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
Sample Input:

5 1 2 4 14 9
3
1 3
2 5
4 1

Sample Output:

3
10
7

=============================================
此题原以为很简单,刚想疑问为啥PAT上正确率就0.2几….自己做了才发现原来会超时,因为数据量很大。
最初的想法超级简单,就是记录下每个顶点间的距离,等到有查询的时候再一个个计算~结果尼玛第三个测试点妥妥的超时了!
肯定是算法有问题,因为算法实在太简单了。
后来嘛,后来去网上一搜,搜了一半想到两个问题:
1.整个圆圈的总长度知道了,我算出一边,那么另一边的长度一减就出来了
2.从点x到点y(假设x小于y)的长度,不就是从 1到y的长度减去从1到x的长度(1点为第一个点)
而从1到i的长度,其实在读入数据的时候不就可以计算了!!!!!

dist_sum[i] = dist[i-1] + currDist;

之所以这两种做法时间上差别那么多,
因为幼稚的方法里面,每次计算时间复杂度是O(n),一共M次查询就是O(M*n)
现在每次查询时间复杂度是O(1),M次查询也就O(M)
题目给的规模,n=100000, M=10000
差距可想而知~
=================================

#include
int getShortestDist(const int* dists, int N, int from, int to, long totalDist)
{
int dist_L, dist_R;
if(from > to)
{
int temp = from;
from = to;
to = temp;
}
dist_L = dists[to-1] - dists[from-1];
dist_R = totalDist - dist_L;
return (dist_L

测试点	结果	用时(ms)	内存(kB)	得分/满分
0	答案正确	0	780	14/14
1	答案正确	0	790	3/3
2	答案正确	10	1000	3/3
Categories
不学无术

1043. Is It a Binary Search Tree (25)

时间限制:400ms
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
  • Both the left and right subtrees must also be binary search trees.

If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.
Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in a line “YES” if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or “NO” if not. Then if the answer is “YES”, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input 1:

7
8 6 5 7 10 8 11

Sample Output 1:

YES
5 7 6 8 11 10 8

Sample Input 2:

7
8 10 11 8 6 7 5

Sample Output 2:

YES
11 8 10 7 5 6 8

Sample Input 3:

7
8 6 8 5 10 9 11

Sample Output 3:

NO

===================================
二叉搜索树与“镜像”的二叉搜索树,其实对称的东西只是部分特殊化了一下,所以搞定非对称的就行。
想了半天怎么用堆栈什么的实现,其实把自己绕紧了无底洞,干脆自定义结构弄嘛!
基本思路如下(对BST来说的)

工作队列q = 输入值
结果队列result = []
初始化根节点root(value)
root.left_bound = [-INF, value]
root.right_bound = [value, INF]
currNode = root
while len(q)>0 and currNode!=None:
当前队首数值为n
if n能放在当前节点左侧:
新建节点newNode
newNode.left_bound = [ currNode.left_bound[0], n]
newNode.right_bound = [ n, currNode.left_bound[1]]
newNode.parent = currNode
q.pop()
elif 能放在右侧:
新建节点newNode
newNode.left_bound = [ currNode.right_bound[0], n]
newNode.right_bound = [ n, currNode.right_bound[1]]
newNode.parent = currNode
######
currNode.cannotPlaceLeft = true
######
q.pop()
else:
result.push(currNode.value)
######
currNode.cannotPlaceLeft = true
######
currNode = currNode.parent
一切处理完之后,
while currNode != None:
result.push(currNode.value)
currNode = currNoew.parent

里面#####中间的一个布尔变量是防止重复访问左侧值设定的,比如说如下情况
8
X 10
此时左边没有东西,但是已经访问过了,如果不设置一个布尔值判断的话,假设当前有那么一个值=6的元素
当前处理位置在10,发现6放不进去,然后移到8的位置
就会觉得8左边可以塞进去
但其实已经是非法操作了
=================================================================

#include
#include
using namespace std;
const int INFI = 65535;
struct Node
{
int value;
Node* left;
Node* right;
Node* parent;
int left_bound[2];
int right_bound[2];
bool left_tried; //已经尝试过左侧
void setLeftBound(int val0, int val1)
{
left_bound[0] = val0;
left_bound[1] = val1;
}
void setRightBound(int val0, int val1)
{
right_bound[0] = val0;
right_bound[1] = val1;
}
bool canPlaceLeft(int val)
{
if(left != NULL)
return false;
if(left_tried)
return false;
if(val >= left_bound[0] && val < left_bound[1]) return true; return false; } bool canPlaceRight(int val) { if(right != NULL) return false; if(val >= right_bound[0] && val < right_bound[1]) return true; return false; } Node() { left = NULL; right = NULL; parent = NULL; setLeftBound(-INFI, INFI); setRightBound(-INFI, INFI); left_tried = false; } }; queue tryBST(queue input)
{
queue result;
Node root;
root.value = input.front();
root.setLeftBound(-INFI, root.value);
root.setRightBound(root.value, INFI);
input.pop();
Node* currNode = &root;
while(!input.empty() && currNode!=NULL)
{
int currVal = input.front();
if(currNode->canPlaceLeft(currVal))
{
//可以放在左侧
Node *pNewNode = new Node;
pNewNode->setLeftBound(currNode->left_bound[0], currVal);
pNewNode->setRightBound(currVal, currNode->left_bound[1]);
pNewNode->parent = currNode;
pNewNode->value = currVal;
currNode->left = pNewNode;
currNode = pNewNode;
input.pop();
}
else if(currNode->canPlaceRight(currVal))
{
//可以放在右侧
Node *pNewNode = new Node;
pNewNode->setLeftBound(currNode->right_bound[0], currVal);
pNewNode->setRightBound(currVal, currNode->right_bound[1]);
pNewNode->parent = currNode;
pNewNode->value = currVal;
currNode->right = pNewNode;
currNode->left_tried = true;
currNode = pNewNode;
input.pop();
}
else
{
result.push(currNode->value);
currNode->left_tried = true;
currNode = currNode->parent;
}
}
while(currNode != NULL)
{
//一直递归到根部加入遍历结果
result.push(currNode->value);
currNode = currNode->parent;
}
return result;
}
queue tryBSTRev(queue input)
{
queue result;
Node root;
root.value = input.front();
root.setRightBound(-INFI, root.value);
root.setLeftBound(root.value, INFI);
input.pop();
Node* currNode = &root;
while(!input.empty() && currNode!=NULL)
{
int currVal = input.front();
if(currNode->canPlaceLeft(currVal))
{
//可以放在左侧
Node *pNewNode = new Node;
pNewNode->setRightBound(currNode->left_bound[0], currVal);
pNewNode->setLeftBound(currVal, currNode->left_bound[1]);
pNewNode->parent = currNode;
pNewNode->value = currVal;
currNode->left = pNewNode;
currNode = pNewNode;
input.pop();
}
else if(currNode->canPlaceRight(currVal))
{
//可以放在右侧
Node *pNewNode = new Node;
pNewNode->setRightBound(currNode->right_bound[0], currVal);
pNewNode->setLeftBound(currVal, currNode->right_bound[1]);
pNewNode->parent = currNode;
pNewNode->value = currVal;
currNode->right = pNewNode;
currNode->left_tried = true;
currNode = pNewNode;
input.pop();
}
else
{
result.push(currNode->value);
currNode->left_tried = true;
currNode = currNode->parent;
}
}
while(currNode != NULL)
{
//一直递归到根部加入遍历结果
result.push(currNode->value);
currNode = currNode->parent;
}
return result;
}
int main()
{
queue input;
int N;
scanf("%d", &N);
for(int i=0; i result1 = tryBST(input);
if(result1.size() == input.size())
{
printf("YESn");
while(!result1.empty())
{
printf("%d", result1.front());
if(result1.size() != 1)
printf(" ");
result1.pop();
}
return 0;
}
result1 = tryBSTRev(input);
if(result1.size() == input.size())
{
printf("YESn");
while(!result1.empty())
{
printf("%d", result1.front());
if(result1.size() != 1)
printf(" ");
result1.pop();
}
return 0;
}
printf("NO");
//
return 0;
}

测试点	结果	用时(ms)	内存(kB)	得分/满分
0	答案正确	0	710	6/6
1	答案正确	0	790	6/6
2	答案正确	0	710	2/2
3	答案正确	0	720	3/3
4	答案正确	0	790	3/3
5	答案正确	0	700	2/2
6	答案正确	0	790	2/2
7	答案正确	0	790	1/1
Categories
不学无术

1063. Set Similarity (25)

时间限制:300ms
Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*100%, where Nc is the number of distinct common numbers shared by the two sets, and Nt is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.
Input Specification:
Each input file contains one test case. Each case first gives a positive integer N (<=50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (<=104) and followed by M integers in the range [0, 109]. After the input of sets, a positive integer K (<=2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.
Output Specification:
For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.
Sample Input:

3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3

Sample Output:

50.0%
33.3%

=====================================
这题目看起来挺简单,但是因为
1.数据量大
2.数值范围大
所以
1.要考虑求交集并集的最佳算法
2.不能用bitmap来用空间换时间
这个求交集并集(数量)的算法其实说来也不难,
有两个集合A,B,先假设
他们并集的大小uSize = |A|+|B|
交集的大小iSize = 0
集合进行排序(最小时间复杂度O(nlogn))后,可以用O(1)的算法找出并集交集:

A元素指针 ptrA = A.begin()
B元素指针 ptrB = B.begin()
while 列表A/B都没有遍历尽:
valA = *ptrA
valB = *ptrB
if valA == valB:
ptrA++
ptrB++
iSize ++
uSize -- #去掉多余的元素
elif valA > valB:
#数值小的往后挪动一格
ptrB++
else:
ptrA++

具体代码如下,后来想想其实用实现更方便一点:)

#include
#include
#include
using namespace std;
double getSimi(vector a, vector b)
{
vector *ptrA = &a;
vector *ptrB = &b;
if( a.size() > b.size())
{
//保证ptrA集合数目小
ptrB = &a;
ptrA = &b;
}
sort(ptrA->begin(), ptrA->end());
sort(ptrB->begin(), ptrB->end());
int iSize = 0;
int uSize = ptrB->size() + ptrA->size();
vector::iterator itA = ptrA->begin();
vector::iterator itB = ptrB->begin();
while(itA != ptrA->end() && itB!=ptrB->end())
{
long valA = *itA;
long valB = *itB;
if(valA == valB)
{
iSize ++;
uSize --;
itA++;
itB++;
}
else if(valA > valB)
{
//B队列下移一位
itB++;
}
else
{
//A队列下移一位
itA++;
}
}
return static_cast(iSize)/uSize;
}
int main()
{
int N;
scanf("%d", &N);
vector *arySets = new vector[N];
for(int i=0; i

测试点	结果	用时(ms)	内存(kB)	得分/满分
0	答案正确	0	720	12/12
1	答案正确	0	720	3/3
2	答案正确	0	790	3/3
3	答案正确	10	790	3/3
4	答案正确	260	990	4/4
Categories
不学无术

1062. Talent and Virtue (25)

About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people’s talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a “sage(圣人)”; being less excellent but with one’s virtue outweighs talent can be called a “nobleman(君子)”; being good in neither is a “fool man(愚人)”; yet a fool man is better than a “small man(小人)” who prefers talent than virtue.
Now given the grades of talent and virtue of a group of people, you are supposed to rank them according to Sima Guang’s theory.
Input Specification:
Each input file contains one test case. Each case first gives 3 positive integers in a line: N (<=105), the total number of people to be ranked; L (>=60), the lower bound of the qualified grades — that is, only the ones whose grades of talent and virtue are both not below this line will be ranked; and H (<100), the higher line of qualification — that is, those with both grades not below this line are considered as the “sages”, and will be ranked in non-increasing order according to their total grades. Those with talent grades below H but virtue grades not are cosidered as the “noblemen”, and are also ranked in non-increasing order according to their total grades, but they are listed after the “sages”. Those with both grades below H, but with virtue not lower than talent are considered as the “fool men”. They are ranked in the same way but after the “noblemen”. The rest of people whose grades both pass the L line are ranked after the “fool men”.
Then N lines follow, each gives the information of a person in the format:

ID_Number Virtue_Grade Talent_Grade

where ID_Number is an 8-digit number, and both grades are integers in [0, 100]. All the numbers are separated by a space.
 
Output Specification:
The first line of output must give M (<=N), the total number of people that are actually ranked. Then M lines follow, each gives the information of a person in the same format as the input, according to the ranking rules. If there is a tie of the total grade, they must be ranked with respect to their virtue grades in non-increasing order. If there is still a tie, then output in increasing order of their ID’s.
Sample Input:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

Sample Output:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

======================================================
此题就是个分几类然后排序的问题,将每个人作为一个对象用STL就很好做了
重载一下运算符<就行了,STL的sort用它来排序的…
切记比较标准的(从C++基础教程上找到的)小于运算符重载的规范

bool operator<( const Object &obj) const;

没啥难度啦~就是有点费时间

#include
#include
#include
using namespace std;
struct Person
{
long id;
int talent;
int virtue;
Person(long _id, int _vir, int _tal)
{
id = _id;
talent = _tal;
virtue = _vir;
}
bool operator<( const Person& p) const { bool flag; //Overload operator < int total_self = talent + virtue; int total_him = p.talent + p.virtue; if(total_self < total_him) flag = true; else if(total_self > total_him)
flag = false;
else
{
if(virtue == p.virtue)
flag = id > p.id; //ID in increasin order!
else
flag = virtue < p.virtue; } return !flag; //Non-increasing order } }; int main() { vector people[4];
int N, L, H;
scanf("%d %d %d", &N, &L, &H);
int M = 0;
for(int i=0; i=H && vir >= H)
{
//Sage
people[0].push_back(p);
}
else if(vir >= H)
{
//Nobleman
people[1].push_back(p);
}
else if(vir >= tal)
{
//Fool
people[2].push_back(p);
}
else
{
//Small man
people[3].push_back(p);
}
}
printf("%dn", M);
for(int i=0; i<4; i++) { //Arrange them sort(people[i].begin(), people[i].end()); //Output for(vector::iterator it=people[i].begin(); it!=people[i].end(); it++)
{
printf("%ld %d %dn", it->id, it->virtue, it->talent);
}
}
return 0;
}

测试点	结果	用时(ms)	内存(kB)	得分/满分
0	答案正确	0	710	12/12
1	答案正确	0	710	2/2
2	答案正确	40	990	3/3
3	答案正确	80	3730	3/3
4	答案正确	80	3800	3/3
5	答案正确	0	790	2/2
Categories
不学无术

1061. Dating (20)

Sherlock Holmes received a note with some strange strings: “Let’s date! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm”. It took him only a minute to figure out that those strange strings are actually referring to the coded time “Thursday 14:04” — since the first common capital English letter (case sensitive) shared by the first two strings is the 4th capital letter ‘D’, representing the 4th day in a week; the second common character is the 5th capital letter ‘E’, representing the 14th hour (hence the hours from 0 to 23 in a day are represented by the numbers from 0 to 9 and the capital letters from A to N, respectively); and the English letter shared by the last two strings is ‘s’ at the 4th position, representing the 4th minute. Now given two pairs of strings, you are supposed to help Sherlock decode the dating time.
Input Specification:
Each input file contains one test case. Each case gives 4 non-empty strings of no more than 60 characters without white space in 4 lines.
Output Specification:
For each test case, print the decoded time in one line, in the format “DAY HH:MM”, where “DAY” is a 3-character abbreviation for the days in a week — that is, “MON” for Monday, “TUE” for Tuesday, “WED” for Wednesday, “THU” for Thursday, “FRI” for Friday, “SAT” for Saturday, and “SUN” for Sunday. It is guaranteed that the result is unique for each case.
Sample Input:

3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm

Sample Output:

THU 14:04

===========================================
题目看上去挺简单,自己做的时候粗心大意轻视了。
注意以下几点:
1.第一次比对的是从’A’-‘G’之内的相同字母,其他任何字符相同的无效
2.第二次比对的是从’0’-‘9’及’A’-‘N’之内的相同字符,其他无效
吐槽下第一次用VS2005感觉比VS2012差了好几条街,根本没有智能提示,估计是我变成习惯不好,编译错了N次…但是免研的时候估计没那么新版本,还是适应一下吧~
============================================

#include
#include
#include
using namespace std;
const char* wkdays[] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
int main()
{
const int BUFFER = 61;
char str1[BUFFER];
int results[3]; //存放四个数字结果
//第一次读取
cin >> str1;
int len1 = strlen(str1);
//第二次读取
char str2[BUFFER];
cin >> str2;
int len2 = strlen(str2);
int endIndex = (len1=7 ) //'G'
continue;
}
else
{
if(chrIndex < 0 || chrIndex >= 14) //'N'
{
if(digIndex <0 || digIndex >9)
continue;
digitFlag = true;//是个数字
}
}
if(str1[i] == str2[i])
{
if(firstTime)
{
results[0] = chrIndex;
firstTime = false;
}
else
{
results[1] = digitFlag? (digIndex):(chrIndex + 10);
break;
}
}
}
//第三次读取
char str3[BUFFER];
char str4[BUFFER];
cin >> str3 >> str4;
int len3 = strlen(str3);
int len4 = strlen(str4);
endIndex = (len3='a' && str3[i]<='z'; bool cond2 = str3[i]>='A' && str3[i]<='Z'; if(cond1 || cond2) { if(str3[i] == str4[i]) { results[2] = i; break; } } } cout << wkdays[results[0]] << " " << setw(2) << std::setfill('0') << results[1] << ":" << setw(2) << std::setfill('0') << results[2]; return 0; }

Categories
不学无术

1064. Complete Binary Search Tree (30)

时间限制
50 ms
内存限制
32000 kB
代码长度限制
16000 B

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
  • Both the left and right subtrees must also be binary search trees.

A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.
Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input:

10
1 2 3 4 5 6 7 8 9 0

Sample Output:

6 3 8 1 5 7 9 0 2 4

========================================
翻译过来就是…完全二叉搜索树
两个特征:二叉搜索树+完全二叉树
后面的代码里面可能有一点冗余的地方,就是那个if里面的,不过运行结果不影响,就没去改了。
我想的办法是自顶向下的,从一堆排好序的数中揪出那个“中间的”,然后分为两棵子树做,如此迭代(具体输出用<queue>的数组一层层弄就行了,这边懒得写):

function foo:
本行完整的应有m = log2(N)个
本行多出的有r = N – m个 (就是完全树的最底下一行多余的节点数)
if r==0:
太完美了..将中间的数找出,放入输出队列中
else:
最后一排填满的话会有k=2^m个元素
那么左右边分开的话,各有k/2个
这样就能算出左边右边应该有多少个元素“多余”,去除左右边多余的剩下就是真正的长度
去除多余的元素,根据长度找出中间的元素,放入输出队列
递归接着算

=======================================================================

#include
#include /* qsort */
#include
#include
using namespace std;
int compare(const void *a, const void *b)
{
return ( *(int*)a - *(int*)b);
}
queue *results;
void run(int* srcAry, int fromIndex, int toIndex, int level)
{
int length = toIndex - fromIndex + 1;
if(length < 1) return; if(length == 1) { //到底了 //printf("%d ", srcAry[fromIndex]); results[level].push(srcAry[fromIndex]); return; } int m = log((double)length)/log((double)2); int r = length - pow(2.0f,m) + 1; if(r == 0) { int midIndex = fromIndex + length/2; //printf("%d ", srcAry[midIndex]); results[level].push(srcAry[midIndex]); run(srcAry, fromIndex, midIndex-1, level-1); run(srcAry, midIndex+1, toIndex, level-1); } else { int k = pow(2.0f, m); int left = k/2, right = k/2; if(r <= left) { //只有左边有 left = r; right = 0; } else { //右边也有 right = r - left; } int restLength = length - r; int midIndex = fromIndex + left + restLength/2; //printf("%d ", srcAry[midIndex]); results[level].push(srcAry[midIndex]); run(srcAry, fromIndex, midIndex -1, level-1); run(srcAry, midIndex+1, toIndex, level-1); } } int main() { int N; scanf("%d", &N); int *ary = new int[N]; for(int i=0; i[level +1];
run(ary, 0, N-1, level);
int count = 1;
level++;
while (level--)
{
queue q = results[level];
while(!q.empty())
{
printf("%d", q.front());
if(count < N) printf(" "); count ++; q.pop(); } } return 0; }

 

Categories
不学无术

1059. Prime Factors (25)

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p1^k1* p2^k2 *…*pm^km.
Input Specification:
Each input file contains one test case which gives a positive integer N in the range of long int.
Output Specification:
Factor N in the format N = p1^k1 * p2^k2 *…*pm^km, where pi‘s are prime factors of N in increasing order, and the exponent ki is the number of pi — hence when there is only one pi, ki is 1 and must NOT be printed out.
Sample Input:

97532468

Sample Output:

97532468=2^2*11*17*101*1291

 
=======================================================
就是一个找质数的问题,其实很简单啦~
切记从小的这头开始尝试,因为试想一下,除掉2,3这种小数字之后,需要尝试的明显少了N多!

#include 
#include 
using namespace std;
const int prime[] =
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };
const int prime_length = 25;
map primeMap;
bool isPrime(long val)
{
    for(int i=0; i 0)
        return primeMap[val];
    //没办法了只能苦算
    for(long x=val/2; x>1; x--)
    {
        if(val%x == 0)
        {
            //合数
            primeMap.insert(pair(val, false));
            return false;
        }
    }
    primeMap.insert(pair(val, true));
    return true;
}
map factorCountMap;  //<素数,指数>
int main()
{
    long input;
    scanf("%ld", &input);
    printf("%ld=", input);
    //
    if(input == 1)
    {
        printf("1");
        return 0;
    }
    //从2开始计算...
    long divisor = 2;
    while(input > 1)
    {
        if(!isPrime(divisor))
        {
            divisor++;
            continue;
        }
        if(input%divisor == 0)
        {
            //有这个素数因子
            if(factorCountMap.count(divisor) > 0)
            {
                factorCountMap[divisor] = factorCountMap[divisor] + 1;
            }
            else
            {
                factorCountMap[divisor] = 1;
            }
            input /= divisor;
        }
        else
            divisor++;
    }
    map::iterator it = factorCountMap.begin();
    for(; it!=factorCountMap.end(); it++)
    {
        if(it != factorCountMap.begin())
            printf("*");
        pair p = *it;
        long factor = p.first;
        long exponent = p.second;
        printf("%ld", factor);
        if(exponent > 1)
            printf("^%ld", exponent);
    }
    return 0;
}
Categories
不学无术

1011. World Cup Betting (20)

With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excited as the best players from the best teams doing battles for the World Cup trophy in South Africa. Similarly, football betting fans were putting their money where their mouths were, by laying all manner of World Cup bets.
Chinese Football Lottery provided a “Triple Winning” game. The rule of winning was simple: first select any three of the games. Then for each selected game, bet on one of the three possible results — namely W for win, T for tie, and L for lose. There was an odd assigned to each result. The winner’s odd would be the product of the three odds times 65%.
For example, 3 games’ odds are given as the following:

 W    T    L
1.1  2.5  1.7
1.2  3.0  1.6
4.1  1.2  1.1

To obtain the maximum profit, one must buy W for the 3rd game, T for the 2nd game, and T for the 1st game. If each bet takes 2 yuans, then the maximum profit would be (4.1*3.0*2.5*65%-1)*2 = 37.98 yuans (accurate up to 2 decimal places).
Input
Each input file contains one test case. Each case contains the betting information of 3 games. Each game occupies a line with three distinct odds corresponding to W, T and L.
Output
For each test case, print in one line the best bet of each game, and the maximum profit accurate up to 2 decimal places. The characters and the number must be separated by one space.
Sample Input

1.1 2.5 1.7
1.2 3.0 1.6
4.1 1.2 1.1

Sample Output

T T W 37.98

============================================================
史上最简单的一道题,直接放代码…

#include 
#include  // std::setprecision
using namespace std;
int main()
{
    float best_odds[3] = {0.0, 0.0, 0.0};
    char mark[3] = {'W','T','L'};
    char best_mark[4] = {' ',' ',' '};
    float result = 1.0;
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
        {
            float temp;
            cin >> temp;
            if(temp > best_odds[i])
            {
                best_odds[i] = temp;
                best_mark[i] = mark[j];
            }
        }
        result *= best_odds[i];
        char out = best_mark[i];
        cout << out << " ";
    }
    result = (result * 0.65 - 1) * 2;
    cout << fixed << setprecision(2) << result;
    return 0;
}
Categories
不学无术

1006. Sign In and Sign Out (25)

At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in’s and out’s, you are supposed to find the ones who have unlocked and locked the door on that day.
Input Specification:
Each input file contains one test case. Each case contains the records for one day. The case starts with a positive integer M, which is the total number of records, followed by M lines, each in the format:

ID_number Sign_in_time Sign_out_time

where times are given in the format HH:MM:SS, and ID number is a string with no more than 15 characters.
Output Specification:
For each test case, output in one line the ID numbers of the persons who have unlocked and locked the door on that day. The two ID numbers must be separated by one space.
Note: It is guaranteed that the records are consistent. That is, the sign in time must be earlier than the sign out time for each person, and there are no two persons sign in or out at the same moment.
Sample Input:

3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40

Sample Output:

SC3021234 CS301133

========================
没什么技术含量,直接贴代码~!
========================

#include 
#include 
#include 
using namespace std;
int compare(int left[], int right[])
{
    //比较两个时间的大小,left比right: 早返回-1, 相等返回0, 晚返回1
    if(left[0] > right[0])
        return 1;
    else if(left[0] < right[0])
        return -1;
    else
    {
        if(left[1] > right[1])
            return 1;
        else if(left[1] < right[1])
            return -1;
        else
        {
            if(left[2] > right[2])
                return 1;
            else if(left[2] < right[2])
                return -1;
            return 0;
        }
    }
}
int main()
{
    int sign_in_time[3] = {23, 59, 59};  //hh,mm,ss
    int sign_out_time[3] = {0, 0, 0};
    char sign_in_user[15]; //最早登入的
    char sign_out_user[15]; //最迟登出的
    int M = 0;
    scanf("%d", &M);
    for(int i=0; i