总体来说,个人英语水平还太蹩脚,此次大部分时间都花在理解题意上了,而且到最后有些题目的意思还是不理解,orz...
链接→2016 UESTC ACM Summer Training Team Selection (2)
In an election with more than two candidates, it is often the case that the winner (the candidate receiving the most votes) receives less than the majority of the votes. Given the results of an election, can you determine the winner, and whether the winner received more than half of the votes?
The first line of input contains a single positive integer T ≤ 500 indicating the number of test cases. The first line of each test case also contains a single positive integer n indicating the number of candidates in the election. This is followed by n lines, with the ith line containing a single nonnegative integer indicating the number of votes candidate i received.
Provide a line of output for each test case. If the winner receives more than half of the votes, print the phrase
majority winner followed by the candidate number of the winner. If the winner does not receive
more than half of the votes, print the phrase minority winner followed by the candidate number of the
winner. If a winner cannot be determined because no single candidate has more vote than others, print the
phrase no winner. The candidate numbers in each case are 1, 2, . . . , n.
解题思路:给你n位候选人获得的选票,问几号候选人是获胜者,如果存在多位获得最多选票的人,输出"no winner";若获得最多选票的人票数超过总票数的一半,输出"majority winner x",x表示候选人的编号(从1开始);否则,输出"minority winner x"
简单题,用数组记录每种票数出现的次数,并用ans记录票数的最大值即可
题目链接→1367 Popular Vote
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 50005; const int M = 40; const int inf = 100000000; const int mod = 2009; int s[N]; int main() { int t,ans,i,n,x,c,sum; scanf("%d",&t); while(t--) { memset(s,0,sizeof(s)); ans=sum=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&x); sum+=x; s[x]++; if(ans<x) ans=x,c=i; } if(s[ans]>1) puts("no winner"); else if(ans>sum/2) printf("majority winner %d\n",c); else printf("minority winner %d\n",c); } return 0; }
Mike and his young daughter Jesse are playing a new card game meant
for kids. The rules are quite simple, each player is dealt a hand of cards.
Each card has one picture on each side. They take turns playing cards
and the first one to run out of cards is the winner.
A player’s turn consists of picking a subset of cards from their hand and
The first line of the input contains a single positive integer T (T ≤ 10) indicating the number of test cases. Each test case begins with a single integer n denoting the number of cards in Mike’s hand. Here 1 ≤ n ≤ 50 000. Following this are n lines, each describing a card in Mike’s hand. The pictures on the cards are represented by integers. The ith card is given by two integers pi , qi where 1 ≤ pi , qi ≤ 2n.
For each test case you should output a single line with the word possible if it ispossible for Mike to play his entire hand in one turn, orimpossible if Mike cannot play his entire hand in one turn.
解题思路:给你n组牌,每组两张,问从n组牌中每组取出一张,是否可以做到n张牌均不相同,若可以,输出"possible";否则,输出"impossible"
说实话,一开始想过很多种方法,但是总是没办法考虑全,后来还是同学给的启发
首先,我们给每组的两张牌之间连一条边,那此题就转变成了求取n条边和m(>=n均可)个点
这时,我们就想到了连通分量,对于每个连通分量,只要满足点的个数大于等于边的个数,就是有解的
也就是说若存在一个连通分量,它的边数大于点数,那就做不到n张牌均不相同,因为n条边是必取的,能取的点太少就意味着存在那么一组牌,我没法取
而判连通分量,我们可以采用并查集来解决
放上几组数据供以测试
Input
3
2 1
3 1
2 3
Output
possible
Input
5
1 1
1 1
2 3
4 5
6 7
Output
Input
4
1 2
1 1
2 2
3 4
Output
Input
3
1 2
1 3
1 4
Output
Input
4
1 1
1 2
2 3
3 3
Output
Input
6
2 1
3 1
2 3
5 6
5 7
6 7
Output
题目链接→1369 Flipping Cards
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 50005; const int M = 40; const int inf = 100000000; const int mod = 2009; int s[2*N],e[2*N],m[2*N],p[N],q[N]; int fun(int x) { if(s[x]!=x) s[x]=fun(s[x]); return s[x]; } int main() { int t,n,i,x,y,k; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n+n;i++) s[i]=i,e[i]=m[i]=0; for(i=0;i<n;i++) { scanf("%d%d",&p[i],&q[i]); x=fun(p[i]); y=fun(q[i]); s[x]=y; } for(i=0;i<n;i++) e[fun(p[i])]++; for(i=1;i<=n+n;i++) m[fun(i)]++; for(i=1;i<=n+n;i++) { k=fun(i); if(e[k]>m[k]) break; } if(i<=n+n) puts("impossible"); else puts("possible"); } return 0; }
A recipe is a list of ingredients and a set of instructions to prepare a dish. It is often written for a particular number of portions. If you have a recipe for 4 portions and you want to make 6 portions, it turns out that simply multiplying the amounts for each ingredient by 1.5 is often wrong! The reason is that the original recipe may have been rounded to the nearest teaspoon, gram, etc., and the rounding errors magnify when a recipe is scaled.
Some recipes are specifically written to ease the task of scaling. These recipes are developed using “Baker’s percentages.” Each ingredient is listed not only by weight (in grams), but also as a percentage relative to the “main ingredient.” The main ingredient will always have a 100% Baker’s percentage. Note that the sum of the Baker’s percentages from all ingredients is greater than 100%, and that the Baker’s percentages of some ingredients may exceed 100%.
Olive Oil
Garlic
Beef
Onions
Raisins
Bouillon |
50.9
12.0
453.6
1134.0
82.5
10.0 |
11.2
2.7
100.0
250.0
18.2
2.2
|
The first line of input specifies a positive integer T ≤ 1000, consisting of the cases to follow. Each case
For each case, print Recipe # followed by a space and the appropriate case number (see sample output
below). This is followed by the list of ingredients and their scaled weights in grams. The name of the
ingredient and its weight should be separated by a single space. Each ingredient is listed on its own line, in
the same order as in the input. After each case, print a line of 40 dashes (’-’). Answers within 0.1g of the
correct result are acceptable.
解题思路:此题题目倒是很长,不过有用的就To scale a recipe里的三点,首先根据输入的P和D计算出缩放倍数factor=D/P,然后找到percentage为100.0的食材,将它的weight*factor即可得到main ingredient的scaled weights in grams,然后循环一遍,根据其他食材的percentage与main ingredient的percentage的比例计算得到其他食材的scaled weights in grams
题目链接→1376 Scaling Recipes
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 25; const int M = 40; const int inf = 100000000; const int mod = 2009; struct recipe { char name[N]; double weight,percentage,ans; }s[N]; int main() { int t,r,p,d,i,k,c=1; scanf("%d",&t); while(t--) { scanf("%d%d%d",&r,&p,&d); double factor=d*1.0/p; for(i=0;i<r;i++) { scanf("%s%lf%lf",s[i].name,&s[i].weight,&s[i].percentage); if(s[i].percentage==100.0) { k=i; s[i].ans=s[i].weight*factor; } } printf("Recipe # %d\n",c++); for(i=0;i<r;i++) { if(i!=k) s[i].ans=s[k].ans*(s[i].percentage/100.0); printf("%s %.1f\n",s[i].name,s[i].ans); } for(i=0;i<40;i++) printf("-"); puts(""); } return 0; }
According to NASA’s web page, there are more than 500 000 pieces of “space
junk” that are tracked. Care must be taken in mission planning so satellites
and other spacecrafts do not collide with these pieces of space junk.
For this problem, we will consider the simplified case in which both the spacecraft
and the space junk can be modelled as spheres that are travelling in a
straight line. Given the current locations of the two spheres as well as their
velocities, when would they collide in the future, if ever?
The first line of input contains a single positive integer T ≤ 500 indicating the number of test cases. Each
For each test case, output a line containing the time (in seconds) at which the spacecraft first collides with
the space junk. If they never collide, print No collision instead. Answers within 0.01 of the correct
result are acceptable.
解题思路:给你两个球体的三维坐标,半径以及它们的方向向量(球体沿方向向量的方向作直线运动),问两个球体会不会发生碰撞,若会,给出发生碰撞的时间;若不会,则输出"No collision"
相信大家拿到这题的时候思路很清晰,要知道两球体是否会发生碰撞,我们只需找到它们俩之间的最小球心距是否小于等于俩球体半径之和即可
那么如何求这个最小球心距呢?假设球心距为d,移动时间为t
首先,我们可以分别得到俩球体的参数方程(因为x,y,z已被占用,我们暂时假设横坐标为a,纵坐标为b,竖坐标为c)
球体1的参数方程:
球体2的参数方程:
那么俩球体的球心距d(划红线部分用a代替,划蓝线部分用b代替,划紫线部分用c代替):
一元二次方程?但是要小心了,这里我们需要特判a=0的情况,这时b也为0,球心距的平方是个定值c,因为题目说俩球体一开始没有接触,那么平行运动的俩球体必然不会发生碰撞
剩下的就是一元二次方程的情况了
当且仅当t=-b/(2*a)时,d取得最小值,但要注意,若t<0,说明俩球体之间的距离一直在增大
判断d与r1+r2之间的关系,若d<=r1+r2,两者会发生碰撞,但此时的时间不一定是最早发生碰撞的时间,这时要求解方程a*t*t+b*t+c=r1+r2的最小非负解
此题说简单也简单,说难也难,主要是看我们能不能推导出公式,只要能推导出公式,剩下的就是细节问题
题目链接→1373 Space Junk
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 100005; const int M = 40; const int inf = 100000000; const int mod = 2009; int main() { int T,x1,y1,z1,r1,vx1,vy1,vz1,x2,y2,z2,r2,vx2,vy2,vz2,a,b,c; double t,d,ans; scanf("%d",&T); while(T--) { scanf("%d%d%d%d%d%d%d",&x1,&y1,&z1,&r1,&vx1,&vy1,&vz1); scanf("%d%d%d%d%d%d%d",&x2,&y2,&z2,&r2,&vx2,&vy2,&vz2); b=2*((x2-x1)*(vx2-vx1)+(y2-y1)*(vy2-vy1)+(z2-z1)*(vz2-vz1)); a=(vx2-vx1)*(vx2-vx1)+(vy2-vy1)*(vy2-vy1)+(vz2-vz1)*(vz2-vz1); c=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1); if(!a) { puts("No collision"); continue; } t=max(1.0*(-b)/2/a,0.0); d=a*t*t+b*t+c; if(d<=(r1+r2)*(r1+r2)+exp)//不考虑精度会WA在第6组 { if(t==0.0) puts("0.000"); else { ans=(-b-sqrt(b*b-4.0*a*(c-(r1+r2)*(r1+r2))))/2/a; printf("%.3f\n",max(ans,0.0)); } } else puts("No collision"); } return 0; }
In his memoir “So, Anyway”, comedian John Cleese writes of the class difference between his father (who was “middle-middle-middle-lower-middle class” and his mother (who was “upper-upper-lower-middle class”). These fine distinctions between classes tend to confuse North American readers, so you are to write a program to sort a group of people by their classes to show their true place in the social class hierarchy.
For this problem, there are three main classes: upper, middle, and lower. Obviously, the highest is upper and the lowest is lower. But there can be distinctions within a class, so upper-upper is a higher class than middle-upper, which is higher than lower-upper. However, all of the upper classes (upper-upper, middle-upper, and lower-upper) are higher than any of the middle classes.
Within a class like middle-upper, there can be further distinctions as well, leading to classes like lower-middle-upper-middle-upper. When comparing classes, once you have reached the lowest level of detail, you should assume that all further classes are the same as the middle level of the previous level of detail. So upper class and middle-upper class are equivalent, as are middle-middle-lower-middle and lower-middle.
The first line of input contains a single positive integer T (T ≤ 500) indicating the number of cases to follow. Each case starts with a positive integer n (n ≤ 100) on a line indicating the number of people to consider. Each of the next n lines contains the name of a person followed by a colon and a space, followed by the class of the person. The name contains up to 30 lowercase characters. The class is a string consisting of a nonempty sequence of up to 10 of the words upper, middle, lower separated by hyphens (-), followed by a space, followed by the word class. No two people will have the same name in a single case.
For each test case, print the list of names from highest to lowest class. If two people have the same or equivalent classes, they should be listed in alphabetical order by name. Output a line of 30 equal signs (=) after each case.
解题思路:此题做法其实很简单,难就难在题意不好理解,至少我一直没弄明白题目意思,然而学长一眼就看出了题意,佩服佩服
其实对于每个class,我们从后往前与其它class进行比较,按照upper>middle>lower
而对于等效类,例如yyyy-xxxx与xxxx(xxxx与yyyy均为upper,middle,lower的组合),题目中红色字体部分做了说明,虽然我自己没有看懂,但是它的意思是等效类前均补middle,yyyy-xxxx与middle-...-middle-xxxx
待将字符串处理完之后,剩下要做的就是简简单单的排序,O(nlogn)或O(n^2)的排序算法均可
若是还不明白的,可以在下方留言
题目链接→1371 A Classy Problem
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 105; const int M = 40; const int inf = 100000000; const int mod = 2009; struct recipe { char name[N],ch[2*N],x[N]; }s[3*N]; char a[10]; bool cmp(recipe x,recipe y) { if(strcmp(x.x,y.x)) return strcmp(x.x,y.x)>0; return strcmp(x.name,y.name)<0; } int main() { int t,n,i,j,k,p,x; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s%s%s",s[i].name,s[i].ch,a); s[i].name[strlen(s[i].name)-1]='\0'; for(p=j=0;s[i].ch[j]!='\0';j++) { if(s[i].ch[j]=='u') { s[i].x[p++]='c'; j+=4; } else if(s[i].ch[j]=='m') { s[i].x[p++]='b'; j+=5; } else if(s[i].ch[j]=='l') { s[i].x[p++]='a'; j+=4; } } s[i].x[p]='\0'; reverse(s[i].x,s[i].x+p); while(p<10) s[i].x[p++]='b'; s[i].x[p]='\0'; //puts(s[i].x); } sort(s,s+n,cmp); for(i=0;i<n;i++) printf("%s\n",s[i].name); for(i=0;i<30;i++) printf("="); puts(""); } return 0; }
There’s no doubt about it, three is a magical number. Two’s company,
Each line of the input contains one nonnegative integer n. The value
For each nonzero value of n in the input, print on a single line the smallest base for which the number has a
representation that ends in 3. If there is no such base, print instead “No such base”.
解题思路:此题要我们找到最小的进制满足n转换成该进制表示时最低位为3,如
若不存在,则输出"No such base"
首先,我们可以知道进制转换是如何实现的
比如要将123转换成4进制
由此可知,要使n转换为x进制后最低位是3,其实就是n mod x = 3,也就是说(n-3)%x==0
要使x尽可能小,所以就是求n-3的最小约数
但是需要注意的是该约数不能小于4,否则x(<4)进制是没法表示3的,这些特判一下就可以了
题目链接→1375 The Magical 3
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 50005; const int M = 40; const int inf = 100000000; const int mod = 2009; int main() { int n,i; bool flag; while(scanf("%d",&n)&&n) { n-=3;flag=false; if(!n) { puts("4"); continue; } else if(n<4) { puts("No such base"); continue; } for(i=4;i<=sqrt(n);i++) if(n%i==0) { flag=true; break; } if(flag) printf("%d\n",i); else { if(n%3==0&&n/3>=4) printf("%d\n",n/3); else if(n%2==0&&n/2>=4) printf("%d\n",n/2); else printf("%d\n",n); } } return 0; }
A matrix keypad consists of an r × c grid of buttons. Additionally, there is one wire for each row and one wire for each column. These wires are
The first line of input contains a single positive integer T ≤ 200 indicating the number of test cases. The first line of each test case contains two integers r and c where 1 ≤ r ≤ 10 and 1 ≤ c ≤ 10. This indicates that the keypad is an r × c grid of buttons.
For each test case, output the following. If there is no combination of button presses on the keypad that would produce this 0/1 grid then simply output a line containing the word impossible
Otherwise, you should output r lines, each containing a string of length c. This should describe a grid where the character at row i and column j is:
• N if no button combination that produces the input grid has the jth button on row i being pressed.
• P if all button combinations that produce the input grid have the jth button on row i being pressed.
• I if some, but not all, button combinations that produce the input grid have the jth button on row i being pressed.
Finally, the last line of each test case should be followed by the string ---------- (10 dashes).
解题思路:此题可以说是一道潜在的水题,之所以这么说是因为比赛的时候仅仅有三个人去做,然而此题却水到不能再水
给你一个0/1矩阵,a(i,j)为1表示第i行至少有一个按钮被按,第j列至少有一个按钮被按,这个按钮可以是同一个(即a(i,j)位置上的那个按钮),也可以是不同的两个,否则a(i,j)为0,现要你确认每个按钮的状态:
N表示这个按钮必定没有被按
P表示这个按钮必定被按
I表示这个按钮可能被按
impossible表示没有按钮组合满足这个0/1矩阵
由于I状态的情况较多,本人是优先判断N,P以及impossible的情况,其余均为I
首先是impossible,不可能的情况只有a(i,j)=0,但第i行和第j列均含有1,这与"The value stored in row i and column j of this grid is 1 if there is at least one button in row i and at least one (possibly different) button in column j that is pressed."矛盾,故为impossible
其次是N,当a(i,j)=0时,除了impossible的情况以外,其他情况下a(i,j)为0必定能够说明a(i,j)处的按钮没有被按下,否则若a(i,j)处的按钮被按下,那第i行第j列都至少有一个按钮被按下,那a(i,j)也就不可能为0了
再者是P,当a(i,j)=1,若第i行或第j列只有这么一处地方是1,那这个地方的按钮必定是被按下的,否则不满足第i行或第j列至少有一个按钮被按下的条件
最后剩下的皆为I
题目链接→1374 Matrix Keypad
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 15; const int M = 40; const int inf = 100000000; const int mod = 2009; char s[N][N],ans[N][N]; int a[N],b[N]; int main() { int t,r,c,i,j; bool flag; scanf("%d",&t); while(t--) { flag=true; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d%d",&r,&c); for(i=0;i<r;i++) scanf("%s",s[i]); for(i=0;i<r;i++) for(j=0;j<c;j++) if(s[i][j]-'0') a[i]++,b[j]++; for(i=0;i<r&&flag;i++) { for(j=0;j<c&&flag;j++) if(s[i][j]-'0') { if(a[i]==1||b[j]==1) ans[i][j]='P'; else ans[i][j]='I'; } else { if(a[i]&&b[j]) flag=false; else ans[i][j]='N'; } ans[i][j]='\0'; } if(flag) { for(i=0;i<r;i++) puts(ans[i]); } else puts("impossible"); for(i=0;i<10;i++) printf("-"); puts(""); } return 0; }
Alice travels a lot for her work. Each time she travels, she
The first line of input contains a single positive integer T ≤ 50 indicating the number of test cases. The first line of each
For each test case, simply output a single line containing a single integer that is the number of distinct cities
that Alice has visited on her work trips.
STL里的set内部其实是一棵红黑树,不知道不要紧,只要知道set里面只会记录下不同的值,最后我只要看看它的size()就知道有多少个不同的字符串
题目链接→1372 I’ve Been Everywhere, Man
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 50005; const int M = 40; const int inf = 100000000; const int mod = 2009; set<string> s; int main() { int t,n,i; string ch; scanf("%d",&t); while(t--) { s.clear(); scanf("%d",&n); for(i=0;i<n;i++) { cin>>ch; s.insert(ch); } printf("%d\n",s.size()); } return 0; }
菜鸟成长记