-
2009-05-24
09年软件工程师笔试题(C/C++笔试题) - [C++]
准确的说,我在找到这篇文章之前从来没觉得他写得如此精辟……即使我不是特意来准备的,我还是应该会从中获益很多的吧……
预处理器(Preprocessor)
1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)... -
SQL递归问题
-
Joseph
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17767 Accepted: 6620 Description
The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.
Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy.
Input
The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14.Output
The output file will consist of separate lines containing m corresponding to k in the input file.Sample Input
3
4
0Sample Output
5
30这道题就是约瑟夫问题的变种,需要计算出要数的数,而最高只要求到14
于是思维正常的人立刻会想到打表发,于是就有了如下这个东西
#include<iostream>
using namespace std;
int array[14]={2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881,13482720};
int main()
{
int k;
while(scanf("%d",&k)){
if(k==0) break;
printf("%d\n",array[k-1]);
}
return 0;
}但是大家要注意了要注意了,这道题给的数据着实变态,这个,可是要16Ms的!
也就是说,就算是打表,还要这么慢!faint,正常怪不得那么慢
但是做题吗,正常做法如下
#include <stdio.h>
#include <string.h>
int main()
{
int arr[15];
memset(arr,0,15*sizeof(int));
while(1)
{
int k,m=0;
scanf("%d",&k);
if(k==0)break;
if(arr[k]==0)
{
while(1)
{
m++;
int bad=k*2,now=0;
while(1)
{
now=(now+m-1)%bad+1;
if(now>k)
{
bad--;
now--;
}
else
break;
}
if(bad==k){arr[k]=m;break;}
}
}
printf("%d\n",arr[k]);
}
}Source
-
2008-07-24
Biorhythms
BiorhythmsTime Limit: 1000MS Memory Limit: 10000K Total Submissions: 41669 Accepted: 11527 Description
Some people believe that there are three cycles in a person's life that start the day he or she is born. These three cycles are the physical, emotional, and intellectual cycles, and they have periods of lengths 23, 28, and 33 days, respectively. There is one peak in each period of a cycle. At the peak of a cycle, a person performs at his or her best in the corresponding field (physical, emotional or mental). For example, if it is the mental curve, thought processes will be sharper and concentration will be easier.
Since the three cycles have different periods, the peaks of the three cycles generally occur at different times. We would like to determine when a triple peak occurs (the peaks of all three cycles occur in the same day) for any person. For each cycle, you will be given the number of days from the beginning of the current year at which one of its peaks (not necessarily the first) occurs. You will also be given a date expressed as the number of days from the beginning of the current year. You task is to determine the number of days from the given date to the next triple peak. The given date is not counted. For example, if the given date is 10 and the next triple peak occurs on day 12, the answer is 2, not 3. If a triple peak occurs on the given date, you should give the number of days to the next occurrence of a triple peak.Input
You will be given a number of cases. The input for each case consists of one line of four integers p, e, i, and d. The values p, e, and i are the number of days from the beginning of the current year at which the physical, emotional, and intellectual cycles peak, respectively. The value d is the given date and may be smaller than any of p, e, or i. All values are non-negative and at most 365, and you may assume that a triple peak will occur within 21252 days of the given date. The end of input is indicated by a line in which p = e = i = d = -1.Output
For each test case, print the case number followed by a message indicating the number of days to the next triple peak, in the form:
Case 1: the next triple peak occurs in 1234 days.
Use the plural form ``days'' even if the answer is 1.Sample Input
0 0 0 0 0 0 0 100 5 20 34 325 4 5 6 7 283 102 23 320 203 301 203 40 -1 -1 -1 -1
Sample Output
Case 1: the next triple peak occurs in 21252 days. Case 2: the next triple peak occurs in 21152 days. Case 3: the next triple peak occurs in 19575 days. Case 4: the next triple peak occurs in 16994 days. Case 5: the next triple peak occurs in 8910 days. Case 6: the next triple peak occurs in 10789 days.
Source
#include <stdio.h>
int main()
{ int p,e,i,d,a,t=0;
while(1)
{
scanf("%d%d%d%d",&p,&e,&i,&d);
if(p==-1)
break;
a=(5544*p+14421*e+1288*i-d+21252)%21252;
if(!a)
a=21252;
printf("Case %d: the next triple peak occurs in %d days.\n",++t,a);
}
return 0;
}p.s.极其简单的一道题,不过用到了中国剩余类定理 -
2008-07-24
Hangover
HangoverTime Limit: 1000MS Memory Limit: 10000K Total Submissions: 32772 Accepted: 15194 Description
How far can you make a stack of cards overhang a table? If you have one card, you can create a maximum overhang of half a card length. (We're assuming that the cards must be perpendicular to the table.) With two cards you can make the top card overhang the bottom one by half a card length, and the bottom one overhang the table by a third of a card length, for a total maximum overhang of 1/2 + 1/3 = 5/6 card lengths. In general you can make n cards overhang by 1/2 + 1/3 + 1/4 + ... + 1/(n + 1) card lengths, where the top card overhangs the second by 1/2, the second overhangs tha third by 1/3, the third overhangs the fourth by 1/4, etc., and the bottom card overhangs the table by 1/(n + 1). This is illustrated in the figure below.

Input
The input consists of one or more test cases, followed by a line containing the number 0.00 that signals the end of the input. Each test case is a single line containing a positive floating-point number c whose value is at least 0.01 and at most 5.20; c will contain exactly three digits.Output
For each test case, output the minimum number of cards necessary to achieve an overhang of at least c card lengths. Use the exact output format shown in the examples.Sample Input
1.00 3.71 0.04 5.19 0.00
Sample Output
3 card(s) 61 card(s) 1 card(s) 273 card(s)
Source
#include<iostream>
using namespace std;const int MAXN=300;int main(){
int i;
double len[MAXN]={0};
for (i=1;i<MAXN;i++){
len[i]=len[i-1]+1.0/(i+1);
}
double get;
while(scanf("%lf",&get)){
if(get==0)
break;
for (i=0;i<MAXN;i++){
if(len[i]>get){
printf("%d card(s)\n",i);
break;
}
}
}
return 0;
}p.s.这道题几乎毫无难度……【捂脸】我为什么要做这道题…… -
2008-07-24
Grandpa is Famous - [POJ]
Grandpa is FamousTime Limit: 2000MS Memory Limit: 30000K Total Submissions: 3416 Accepted: 1757 Description
The whole family was excited by the news. Everyone knew grandpa had been an extremely good bridge player for decades, but when it was announced he would be in the Guinness Book of World Records as the most successful bridge player ever, whow, that was astonishing!
The International Bridge Association (IBA) has maintained, for several years, a weekly ranking of the best players in the world. Considering that each appearance in a weekly ranking constitutes a point for the player, grandpa was nominated the best player ever because he got the highest number of points.
Having many friends who were also competing against him, grandpa is extremely curious to know which player(s) took the second place. Since the IBA rankings are now available in the internet he turned to you for help. He needs a program which, when given a list of weekly rankings, finds out which player(s) got the second place according to the number of points.Input
The input contains several test cases. Players are identified by integers from 1 to 10000. The first line of a test case contains two integers N and M indicating respectively the number of rankings available (2 <= N <= 500) and the number of players in each ranking (2 <= M <= 500). Each of the next N lines contains the description of one weekly ranking. Each description is composed by a sequence of M integers, separated by a blank space, identifying the players who figured in that weekly ranking. You can assume that:
- in each test case there is exactly one best player and at least one second best player,
- each weekly ranking consists of M distinct player identifiers.
The end of input is indicated by N = M = 0.Output
For each test case in the input your program must produce one line of output, containing the identification number of the player who is second best in number of appearances in the rankings. If there is a tie for second best, print the identification numbers of all second best players in increasing order. Each identification number produced must be followed by a blank space.Sample Input
4 5
20 33 25 32 99
32 86 99 25 10
20 99 10 33 86
19 33 74 99 32
3 6
2 34 67 36 79 93
100 38 21 76 91 85
32 23 85 31 88 1
0 0Sample Output
32 33
1 2 21 23 31 32 34 36 38 67 76 79 88 91 93 100Source
#include<iostream>
using namespace std;
const int MAX=10000+50;
int main(){
int m,n;
while(scanf("%d %d",&n,&m)){
if (n==0&&m==0)break;
else{
int count[MAX]={0};
int i,j;
int x;
int maxnum=0;
for(i=0;i<n;i++){
for (j=0;j<m;j++){
scanf("%d",&x);
if (x>maxnum) maxnum=x;
count[x]++;
}
}
int first=0,second=0;
for (i=0;i<=maxnum;i++){
if (count[i]>first){
second=first;
first=count[i];
}
if (count[i]>second&&count[i]!=first){
second=count[i];
}
}
for (i=0;i<=maxnum;i++){
if (count[i]==second){
printf("%d ",i);
}
}
cout<<endl;
}
}
return 0;
} -
2008-07-24
An Old Stone Game - [POJ]
An Old Stone GameTime Limit: 1000MS Memory Limit: 10000K Total Submissions: 1002 Accepted: 449 Description
There is an old stone game, played on an arbitrary general tree T. The goal is to put one stone on the root of T observing the following rules:
- At the beginning of the game, the player picks K stones and puts them all in one bucket.
- At each step of the game, the player can pick one stone from the bucket and put it on any empty leaf.
- When all of the r immediate children of a node p each has one stone, the player may remove all of these r stones, and put one of the stones on p. The other r - 1 stones are put back into the bucket, and can be used in the later steps of the game.
The player wins the game if by following the above rules, he succeeds to put one stone on the root of the tree.
You are to write a program to determine the least number of stones to be picked at the beginning of the game (K), so that the player can win the game on the given input tree.Input
The input describes several trees. The first line of this file is M, the number of trees (1 <= M <= 10). Description of these M trees comes next in the file. Each tree has N < 200 nodes, labeled 1, 2, ... N, and each node can have any possible number of children. Root has label 1. Description of each tree starts with N in a separate line. The following N lines describe the children of all nodes in order of their labels. Each line starts with a number p (1 <= p <= N, the label of one of the nodes), r the number of the immediate children of p, and then the labels of these r children.Output
One line for each input tree showing the minimum number of stones to be picked in step 1 above, in order to win the game on that input tree.Sample Input
2
7
1 2 2 3
2 2 5 4
3 2 6 7
4 0
5 0
6 0
7 0
12
1 3 2 3 4
2 0
3 2 5 6
4 3 7 8 9
5 3 10 11 12
6 0
7 0
8 0
9 0
10 0
11 0
12 0Sample Output
3
4Source
#include<iostream>
using namespace std;
struct node{
int Childnum;
int* Child;
int minstone;
};
int CalculateMinStone(int x,node* Array){
node* cur=Array+x;
if (cur->Childnum ==0){
cur->minstone=1;
return 1;
}int i;
for (i=0;i<cur->Childnum;i++){
if(Array[cur->Child[i]].minstone==-1)
Array[cur->Child[i]].minstone=CalculateMinStone(cur->Child[i],Array);
}
int* temp=new int[cur->Childnum+5];
for (i=0;i<cur->Childnum;i++){
temp[i]=Array[cur->Child[i]].minstone;
}
int t;
for(i=0;i<cur->Childnum;i++){
int largest=i;
for(int j=i+1;j<cur->Childnum;j++){
if (temp[largest]<temp[j]){
largest=j;
}
}
t=temp[largest];
temp[largest]=temp[i];
temp[i]=t;
}
int max=temp[0];
for (i=1;i<cur->Childnum;i++){
if (temp[i]+i>max){
max=temp[i]+i;
}
}
return max;
}
int main(){
int time;
node *Array;
cin>>time;
while(time--){
int n;
int x,NumOfChild;
scanf("%d",&n);
Array=new node[n+5];
int i,j;
for(i=0;i<n;i++){
cin>>x>>NumOfChild;
Array[x].Childnum=NumOfChild;
Array[x].Child=new int[NumOfChild+5];
for (j=0;j<NumOfChild;j++){
cin>>Array[x].Child[j];
}
Array[x].minstone=-1;
}
cout<<CalculateMinStone(1,Array)<<endl;
}
return 0;
} -
2008-07-24
Calling Extraterrestrial Intelligence Again - [POJ]
Calling Extraterrestrial Intelligence AgainTime Limit: 1000MS Memory Limit: 65536K Total Submissions: 6138 Accepted: 2704 Description
A message from humans to extraterrestrial intelligence was sent through the Arecibo radio telescope in Puerto Rico on the afternoon of Saturday November 16, 1974. The message consisted of 1679 bits and was meant to be translated to a rectangular picture with 23 x 73 pixels. Since both 23 and 73 are prime numbers, 23 x 73 is the unique possible size of the translated rectangular picture each edge of which is longer than 1 pixel. Of course, there was no guarantee that the receivers would try to translate the message to a rectangular picture. Even if they would, they might put the pixels into the rectangle incorrectly. The senders of the Arecibo message were optimistic.
We are planning a similar project. Your task in the project is to find the most suitable width and height of the translated rectangular picture. The term "most suitable" is defined as follows. An integer m greater than 4 is given. A positive fraction a/b less than or equal to 1 is also given. The area of the picture should not be greater than m. Both of the width and the height of the translated picture should be prime numbers. The ratio of the width to the height should not be less than a/b nor greater than 1. You should maximize the area of the picture under these constraints.
In other words, you will receive an integer m and a fraction a/b. It holds that m > 4 and 0 < a/b <= 1. You should find the pair of prime numbers p, q such that pq <= m and a/b <= p/q <= 1, and furthermore, the product pq takes the maximum value among such pairs of two prime numbers. You should report p and q as the "most suitable" width and height of the translated picture.Input
The input is a sequence of at most 2000 triplets of positive integers, delimited by a space character in between. Each line contains a single triplet. The sequence is followed by a triplet of zeros, 0 0 0, which indicates the end of the input and should not be treated as data to be processed.
The integers of each input triplet are the integer m, the numerator a, and the denominator b described above, in this order. You may assume 4 < m <= 100000 and 1 <= a <= b <= 1000.Output
The output is a sequence of pairs of positive integers. The i-th output pair corresponds to the i-th input triplet. The integers of each output pair are the width p and the height q described above, in this order.
Each output line contains a single pair. A space character is put between the integers as a delimiter. No other characters should appear in the output.Sample Input
5 1 2 99999 999 999 1680 5 16 1970 1 1 2002 4 11 0 0 0Sample Output
2 2 313 313 23 73 43 43 37 53Source
#include<iostream>
#include<cmath>
using namespace std;
const int max_M=100000;
const int primerange=8000;
int main(){
int i,j;
bool Num[primerange];
int primeNum=0;
int Prime[primerange/5];
for (i=2;i<primerange;i++){Num[i]=1;}
Num[0]=Num[1]=0;
for (i=2;i<primerange;i++){
if (Num[i]==1){
Prime[primeNum++]=i;
for (j=2;j*i<primerange;j++){
Num[j*i]=0;
}
}
}
int m,a,b,p,q;
while(scanf("%d %d %d",&m,&a,&b)){
if(m==0&&a==0&&b==0)break;
int mm=pow(m,0.5);
int pp=pow(m*b/a,0.5);
int pq=1;
for (i=primeNum-2;Prime[i+1]>mm;i--){
if (Prime[i]>m||Prime[i]>pp)continue;
for (j=0;j<=i;j++){
if(((double)Prime[j]/Prime[i])<(double)a/b)continue;
else if(Prime[j]*Prime[i]>m)break;
else if(Prime[j]*Prime[i]>pq){
p=Prime[j];q=Prime[i];pq=p*q;
}
}
}
printf("%d %d\n",p,q);
}
return 0;
} -
2008-07-24
Game of Connections - [POJ]
Game of ConnectionsTime Limit: 1000MS Memory Limit: 30000K Total Submissions: 2792 Accepted: 1571 Description
This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, . . . , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another.
And, no two segments are allowed to intersect.
It's still a simple game, isn't it? But after you've written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right?Input
Each line of the input file will be a single positive number n, except the last line, which is a number -1.
You may assume that 1 <= n <= 100.Output
For each n, print in a single line the number of ways to connect the 2n numbers into pairs.Sample Input
2
3
-1Sample Output
2
5Source
#include<iostream>
using namespace std;
const int g=15;
void Add(int * Num1,int * Num2){
int d=0,dtemp=0;
for(int i=0;i<g;i++){
dtemp=(Num1[i]+Num2[i]+d)/10000;
Num1[i]=(Num1[i]+Num2[i]+d)%10000;
d=dtemp;
}
}
int * Muli(int* Num1,int * Num2,int * temp){
int i;
for(i=0;i<g;i++){
if (Num2[i]==0) break;
int t[g]={0};
int d=0;
int j;
for (j=0;j<g;j++){
if (Num1[j]==0) break;
t[j]=(Num1[j]*Num2[i]+d)%10000;
d=(Num1[j]*Num2[i]+d)/10000;
}
t[j]+=d;
Add(temp+i,t);
}
return temp;
}
int* Connect(int n,int ** Con){
if (Con[n][0]!=0) return Con[n];
for(int i=0;i<n;i++){
int temp[2*g]={0};
Add(Con[n],Muli(Con[i],Con[n-1-i],temp));
}
return Con[n];
}
void print(int * N){
for(int i=g-1;i>=0;i--){
if (N[i]==0) continue;
else{
printf("%d",N[i]);
for (int j=i-1;j>=0;j--){
printf("%04d",N[j]);
}
printf("\n");
break;
}
}
}
int main(){
int i;
int ** Con=new int*[105];
for (i=0;i<105;i++){
Con[i]=new int [g+1];
for (int j=0;j<g;j++)
Con[i][j]=0;
}
Con[0][0]=1;
Con[1][0]=1;
int n;
while(scanf("%d",&n)){
if (n==-1) break;
for (i=2;i<=n;i++)
Connect(i,Con);
print(Con[n]);
}
return 0;
}
-
2008-07-24
Bad Cowtractors - [POJ]
Bad CowtractorsTime Limit: 1000MS Memory Limit: 65536K Total Submissions: 3588 Accepted: 1739 Description
Bessie has been hired to build a cheap internet network among Farmer John's N (2 <= N <= 1,000) barns that are conveniently numbered 1..N. FJ has already done some surveying, and found M (1 <= M <= 20,000) possible connection routes between pairs of barns. Each possible connection route has an associated cost C (1 <= C <= 100,000). Farmer John wants to spend the least amount on connecting the network; he doesn't even want to pay Bessie.
Realizing Farmer John will not pay her, Bessie decides to do the worst job possible. She must decide on a set of connections to install so that (i) the total cost of these connections is as large as possible, (ii) all the barns are connected together (so that it is possible to reach any barn from any other barn via a path of installed connections), and (iii) so that there are no cycles among the connections (which Farmer John would easily be able to detect). Conditions (ii) and (iii) ensure that the final set of connections will look like a "tree".Input
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Each line contains three space-separated integers A, B, and C that describe a connection route between barns A and B of cost C.Output
* Line 1: A single integer, containing the price of the most expensive tree connecting all the barns. If it is not possible to connect all the barns, output -1.Sample Input
5 8
1 2 3
1 3 7
2 3 10
2 4 4
2 5 8
3 4 6
3 5 2
4 5 17Sample Output
42
Hint
OUTPUT DETAILS:
The most expensive tree has cost 17 + 8 + 10 + 7 = 42. It uses the following connections: 4 to 5, 2 to 5, 2 to 3, and 1 to 3.Source
#include<iostream>
using namespace std;
const int maxS=1000+1;
int Matrix[maxS][maxS];
int sum=0;
int n;
int Temp[maxS];
bool b[maxS];
void PrimBuild()
{
int max,j,index,i;
memset(b,0,n);
b[0]=1;
for(i=0;i<n;i++){
if(Matrix[0][i]!=-1)
Temp[i]=Matrix[0][i];
else
Temp[i]=-1;
}
for(i=0;i<n-1;i++)
{
max=-1;
index=0;
for(j=1;j<n;j++){
if(max<Temp[j] && b[j]==0){ //找到与当前树中结点相连的最大的一条边
index=j; //记录地址
max=Temp[j]; //记录长度
}
}
if(Temp[index]==-1){ //没有这样的点,数据有误,跳出
sum=-1;
return;
}
b[index]=1; //选定该结点
sum=sum+max;
for(j=0;j<n;j++) //更新Temp数组
{
//当且仅当这个结点存在,未被标记过,且有价值(插入后比原先权重大)
if(Matrix[index][j]!=-1&&b[j]==0&&Matrix[index][j]>Temp[j])
Temp[j]=Matrix[index][j];
}
}
}
int main()
{
int m,x,y;
scanf("%d %d",&n,&m);
int i;
for(i=0;i<n;i++)
memset(Matrix[i],-1,n*sizeof(int));
int temp;
for(i=0;i<m;i++) //输入数据
{
scanf("%d %d %d",&x,&y,&temp);
if (Matrix[x-1][y-1]<temp){
Matrix[x-1][y-1]=temp;
Matrix[y-1][x-1]=temp;
}
}
PrimBuild();
printf("%d\n",sum);
return 0;
} -
2008-07-24
I-Keyboard - [POJ]
I-KeyboardTime Limit: 2000MS Memory Limit: 32768K Total Submissions: 3135 Accepted: 1648 Description
Most of you have probably tried to type an SMS message on the keypad of a cellular phone. It is sometimes very annoying to write longer messages, because one key must be usually pressed several times to produce a single letter. It is due to a low number of keys on the keypad. Typical phone has twelve keys only (and maybe some other control keys that are not used for typing). Moreover, only eight keys are used for typing 26 letters of an English alphabet. The standard assignment of letters on the keypad is shown in the left picture:
1
2
abc3
def4
ghi5
jkl6
mno7
pqrs8
tuv9
wxyz*
0
space#
1
2
abcd3
efg4
hijk5
lm6
nopq7
rs8
tuv9
wxyz*
0
space#
There are 3 or 4 letters assigned to each key. If you want the first letter of any group, you press that key once. If you want the second letter, you have to press the key twice. For other letters, the key must be pressed three or four times. The authors of the keyboard did not try to optimise the layout for minimal number of keystrokes. Instead, they preferred the even distribution of letters among the keys. Unfortunately, some letters are more frequent than others. Some of these frequent letters are placed on the third or even fourth place on the standard keyboard. For example, S is a very common letter in an English alphabet, and we need four keystrokes to type it. If the assignment of characters was like in the right picture, the keyboard would be much more comfortable for typing average English texts.
ACM have decided to put an optimised version of the keyboard on its new cellular phone. Now they need a computer program that will find an optimal layout for the given letter frequency. We need to preserve alphabetical order of letters, because the user would be confused if the letters were mixed. But we can assign any number of letters to a single key.Input
There is a single positive integer T on the first line of input. It stands for the number of test cases to follow. Each test case begins with a line containing two integers K, L (1 <= K <= L <= 90) separated by a single space. K is the number of keys, L is the number of letters to be mapped onto those keys. Then there are two lines. The first one contains exactly K characters each representing a name of one key. The second line contains exactly L characters representing names of letters of an alphabet. Keys and letters are represented by digits, letters (which are case-sensitive), or any punctuation characters (ASCII code between 33 and 126 inclusively). No two keys have the same character, no two letters are the same. However, the name of a letter can be used also as a name for a key.
After those two lines, there are exactly L lines each containing exactly one positive integer F1, F2, ... FL. These numbers determine the frequency of every letter, starting with the first one and continuing with the others sequentially. The higher number means the more common letter. No frequency will be higher than 100000.Output
Find an optimal keyboard for each test case. Optimal keyboard is such that has the lowest "price" for typing average text. The price is determined as the sum of the prices of each letter. The price of a letter is a product of the letter frequency (Fi) and its position on the key. The order of letters cannot be changed, they must be grouped in the given order.
If there are more solutions with the same price, we will try to maximise the number of letters assigned to the last key, then to the one before the last one etc.
More formally, you are to find a sequence P1, P2, ... PL representing the position of every letter on a particular key. The sequence must meet following conditions:
P1 = 1
for each i>1, either Pi = Pi-1+1 or Pi = 1
there are at most K numbers Pi such that Pi = 1
the sum of products SP = F1*P1+F2*P2+...+FL*PL is minimal
for any other sequence Q meeting these criteria and with the same sum SQ = SP, there exists such M, 1 <= M <= L that for any J, M < J <= L, PJ = QJ, and PM > QM.
The output for every test case must start with a single line saying Keypad #I:, where I is a sequential order of the test case, starting with 1. Then there must be exactly K lines, each representing one letter, in the same order that was used in input. Each line must contain the character representing the key, a colon, one space and a list of letters assigned to that particular key. Letters are not separated from each other.
Print one blank line after each test case, including the last one.Sample Input
1
8 26
23456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
3371
589
1575
1614
6212
971
773
1904
2989
123
209
1588
1513
2996
3269
1080
121
2726
3083
4368
1334
518
752
427
733
871Sample Output
Keypad #1:
2: ABCD
3: EFG
4: HIJK
5: LM
6: NOPQ
7: RS
8: TUV
9: WXYZSource
#include <iostream>
using namespace std;
int count[80],num,MIN[80][80],len[80][80],record[80][80];
char number[80],figure[80];
int main()
{
int n,Case,k=0,t=0,m=0;
cin>>Case;
while(Case--)
{
t=k=0;
cin>>n>>num;
int i;
for (i=0;i<num;i++){
for (int j=2;j<=n;j++){
MIN[i][j]=99999999;
}
}
cin>>number>>figure;
for (i=0;i<num;i++)
cin>>count[i];
for (i=0;i<num;i++)
record[i][i]=count[i];
for (i=0;i<num;i++)
for (int j=i+1;j<num;j++)
record[i][j]=record[i][j-1]+(j-i+1)*count[j];
for (i=0;i<num;i++){
len[i][1]=num-1;
MIN[i][1]=record[i][num-1];
}
int total=0;
for (i=2;i<=n;i++)
for (int j=num;j>=0;j--){
for (int t=0;(t+j+i-1)<num;t++){
total=record[j][j+t]+MIN[j+t+1][i-1];
if (total<MIN[j][i]){
MIN[j][i]=total;
len[j][i]=j+t;
}
}
}
cout<<"Keypad #"<<++m<<":"<<endl;
i=0;
while(n){
cout<<number[t]<<": ";
int temp=len[i][n--];
for (i;i<=temp;i++)
cout<<figure[i];
cout<<endl;
t++;
}
cout<<endl;
}
return 0;
}
-
2008-07-24
Pre-Post-erous! - [POJ]
Pre-Post-erous!Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1223 Accepted: 760 Description
We are all familiar with pre-order, in-order and post-order traversals of binary trees. A common problem in data structure classes is to find the pre-order traversal of a binary tree when given the in-order and post-order traversals. Alternatively, you can find the post-order traversal when given the in-order and pre-order. However, in general you cannot determine the in-order traversal of a tree when given its pre-order and post-order traversals. Consider the four binary trees below:
a a a a
/ / \ \
b b b b
/ \ / \
c c c c
All of these trees have the same pre-order and post-order traversals. This phenomenon is not restricted to binary trees, but holds for general m-ary trees as well.Input
Input will consist of multiple problem instances. Each instance will consist of a line of the form
m s1 s2
indicating that the trees are m-ary trees, s1 is the pre-order traversal and s2 is the post-order traversal.All traversal strings will consist of lowercase alphabetic characters. For all input instances, 1 <= m <= 20 and the length of s1 and s2 will be between 1 and 26 inclusive. If the length of s1 is k (which is the same as the length of s2, of course), the first k letters of the alphabet will be used in the strings. An input line of 0 will terminate the input.Output
For each problem instance, you should output one line containing the number of possible trees which would result in the pre-order and post-order traversals for the instance. All output values will be within the range of a 32-bit signed integer. For each problem instance, you are guaranteed that there is at least one tree with the given pre-order and post-order traversals.Sample Input
2 abc cba
2 abc bca
10 abc bca
13 abejkcfghid jkebfghicda
0Sample Output
4
1
45
207352860Source
#include<iostream>
#include<string>
using namespace std;
struct TreeNode{
char value;
TreeNode * LeftMostChild, *RightSibling;
};
TreeNode * BuildTree(string pre,string post){
if (pre.length()==0) return NULL;
TreeNode * root=new TreeNode;
root->value=pre[0];
string pre1,post1,pre2,post2;
int i=0;
while(post[i]!=pre[0]){
post1+=post[i];
pre1+=pre[i+1];
i++;
}
i++;
while(i!=pre.length()){
post2+=post[i];
pre2+=pre[i];
i++;
}
root->LeftMostChild=BuildTree(pre1,post1);
root->RightSibling=BuildTree(pre2,post2);
return root;
}
int Calculate(int k,TreeNode * root){
if (root->LeftMostChild==NULL) return 1;
int ChildNum=1;
TreeNode * pointer=root->LeftMostChild;
while(pointer->RightSibling){
pointer=pointer->RightSibling;
ChildNum++;
}
int sum=1;
int i;
for (i=0;i<ChildNum;i++) sum*=k-i;
for (i=1;i<=ChildNum;i++) sum/=i;
int accum=sum;
pointer=root->LeftMostChild;
while(pointer->RightSibling){
accum*=Calculate(k,pointer);
pointer=pointer->RightSibling;
}
accum*=Calculate(k,pointer);
return accum;
}
int main(){
int k;
string pre,post;
while(scanf("%d",&k)){
if (k==0) break;
cin>>pre>>post;
TreeNode* root=BuildTree(pre,post);
printf("%d\n",Calculate(k,root));
}
return 0;
} -
2008-07-24
Anniversary Cake - [POJ]
Anniversary CakeTime Limit: 1000MS Memory Limit: 10000K Total Submissions: 6577 Accepted: 1967 Description
Nahid Khaleh decides to invite the kids of the "Shahr-e Ghashang" to her wedding anniversary. She wants to prepare a square-shaped chocolate cake with known size. She asks each invited person to determine the size of the piece of cake that he/she wants (which should also be square-shaped). She knows that Mr. Kavoosi would not bear any wasting of the cake. She wants to know whether she can make a square cake with that size that serves everybody exactly with the requested size, and without any waste.Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by input data for each test case. Each test case consist of a single line containing an integer s, the side of the cake, followed by an integer n (1 ≤ n ≤ 16), the number of cake pieces, followed by n integers (in the range 1..10) specifying the side of each piece.Output
There should be one output line per test case containing one of the words KHOOOOB! or HUTUTU! depending on whether the cake can be cut into pieces of specified size without any waste or not.Sample Input
2
4 8 1 1 1 1 1 3 1 1
5 6 3 3 2 1 1 1Sample Output
KHOOOOB!
HUTUTU!Source
Tehran 2002, First Iran Nationwide Internet Programming Contest- Source Code
#include<iostream>
using namespace std;
const int MSoE=12;
const int MAX=40+1;
bool Cake[MAX][MAX]={0};
int SoE[MSoE+1]={0};
int currentmax=MSoE;
int s,nn;
bool sta=0;
void set(int i,int j,int len){
for (int ii=i;ii<i+len;ii++){
for (int jj=j;jj<j+len;jj++){
Cake[ii][jj]=1;
}
}
}
void putback(int i,int j,int len){
for (int ii=i;ii<i+len;ii++){
for (int jj=j;jj<j+len;jj++){
Cake[ii][jj]=0;
}
}
}
bool check(int i,int j,int len){
for (int jj=j;jj<len+j;jj++){
if (Cake[i][jj]==1)return 0;
}
return 1;
}
void put(){
if (nn==0){sta=1;return;}
int i,j;
for (i=0;i<s;i++){
for(j=0;j<s;j++){
if (Cake[i][j]==0){
int len=currentmax;
while(SoE[len]==0){len--;}
while(len){
if(SoE[len]==0||j+len>s||i+len>s||!check(i,j,len)){len--;continue;}
set(i,j,len);
SoE[len]--;
nn--;
put();
if (sta==1)return;
putback(i,j,len);
SoE[len]++;
nn++;
len--;
}
if (Cake[i][j]==0)return;
}
}
}
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
int i;
for (i=0;i<s;i++){
memset(Cake[i],0,s);
}
for (i=0;i<MSoE;i++){
SoE[i]=0;
}
currentmax=MSoE;
scanf("%d %d",&s,&n);
nn=n;
int size;
int space=0;
while(n--){
scanf("%d",&size);
SoE[size]++;
space+=size*size;
}
if (space!=s*s){
printf("HUTUTU!\n");
continue;
}
while(SoE[currentmax]==0){
currentmax--;
}
put();
if (sta==1){
printf("KHOOOOB!\n");
}
else printf("HUTUTU!\n");
sta=0;
}
return 0;
}







