A - Watermelon水题:将一个K千克的西瓜分成2份,每一份都是偶数的可能性。只要注意2这个特殊的点即可。 B - Before an Exam题意:Peter还有几天就考试了,他父母给他安排了一个时间表,第i天最多复习Maxi个小时,最少复习Mini个小时,Peter只记得他一用复习了Sum个小时,是否能够满足父母给他的安排!思路:求出最少时间和s1、最大时间和s2,如果Sum在[s1,s2]之间就一定可以满足条件。第i天最多复习Maxi天,最少Mini天,所以枚举第i天的复习时间j,只要总时间Sum-j>s1-Mini&&Sum-j<s2-Maxi即可。递归的分析下去即可得到结果。 #include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 50+5;const int MAX = 2147483647;int prime [25] = {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};int MinT[N],MaxT[N];int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);// srand((unsigned)time(NULL)); int d,s,s1,s2; while(scanf("%d %d",&d,&s)!=EOF) { s1 = 0,s2 = 0; for(int i=1;i<=d;i++) { scanf("%d %d",&MinT[i],&MaxT[i]); s1 += MinT[i]; s2 += MaxT[i]; } if(s>s2||s<s1) { printf("NO\n"); } else { printf("YES\n"); int i,j; for(i=1;i<d;i++) { s1 -= MinT[i]; s2 -= MaxT[i]; for(j=MinT[i];j<=MaxT[i];++j) { if(s-j<=s2&&s-j>=s1)break; } s -= j; printf("%d ",j); }printf("%d\n",s); } }}
C- Registration system题意:注册系统中的用户名问题,如果用户名未出现过则可用,否则在用户名末尾加上用户名出现的次序。思路:STL中的map的简单应用 D - Mysterious Present题意:1个明信片,n个信封,长宽分别为h、w,组成一个链A={a1,a2,a3...an},其中第i个信封的长宽分别大于第i-1个信封的长宽,链的长度最大为多少,和链中每个信封在输入数据中的位置。思路:按w、h排序后,求一下最长上升子序列 #include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 5000+5;const int MAX = 2147483647;int prime [25] = {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};int ans[N],dp[N],pre[N];struct enve{ int w,h; int num;}enves[N];bool cmp(const enve& a,const enve& b){ if(a.w == b.w) return a.h<b.h; else return a.w<b.w;}int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);// srand((unsigned)time(NULL)); int n,w,h; while(scanf("%d %d %d",&n,&w,&h)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d %d",&enves[i].w,&enves[i].h);enves[i].num = i; } sort(enves+1,enves+n+1,cmp); enves[0].w = w; enves[0].h = h; int k=0,e,tmp; dp[0]=0; for(int i=1;i<=n;i++) { dp[i]=1;pre[i]=i; } for(int i=0;i<=n;i++) { for(int j=0;j<i;j++) { if(enves[0].w<enves[j].w&&enves[0].h<enves[j].h&&enves[j].w<enves[i].w&&enves[j].h<enves[i].h&&dp[i]<dp[j]+1) { dp[i] = dp[j]+1; pre[i] = j;//记录前驱,即从哪个点过来的 } } } for(int i=1;i<=n;i++) { if(dp[i]>k&&enves[0].w<enves[i].w&&enves[0].h<enves[i].h) { k = dp[i]; e = i; }//找到最长子序列并记录它的下标 } tmp = k; while(tmp>0) { ans[tmp] = enves[e].num; e = pre[e]; tmp--; //找到子序列中所有的点 } if(k==0) { printf("0\n"); } else { printf("%d\n",k); for(int i=1;i<k;i++) { printf("%d ",ans[i]); }printf("%d\n",ans[k]); } } return 0;}
E - Triangle题意:四条边能否组成三角形、蜕化三角形(两边之和等于第三边)思路:p=(a+b+c)/2; s = sqrt(p*(p-a)*(p-b)*(p-c));若p*(p-a)*(p-b)*(p-c)>0则为三角形,=0则为蜕化三角形,<0则无法组成三角形 #include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 200+5;const int MAX = 2147483647;int prime [25] = {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};int arr[4];int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);// srand((unsigned)time(NULL)); while(scanf("%d %d %d %d",&arr[0],&arr[1],&arr[2],&arr[3])!=EOF) { int ans=0,flag=0; double p,tmp; for(int i=0;i<4;i++) { p = 0; for(int j=0;j<4;j++) { if(j==i)continue; p += arr[j]; } p/=2.0; tmp = p; for(int j=0;j<4;j++) { if(i==j)continue; tmp *= (p-arr[j]); }// printf("===%.2lf\n",tmp); if(tmp>0) { printf("TRIANGLE\n"); flag = 1; break; }else if(tmp==0) { ans += 0; }else { ans += -1; } } if(!flag) { if(ans>-4) { printf("SEGMENT\n"); }else { printf("IMPOSSIBLE\n"); } } }}
F - President's Office题意:给出一个办公室的分布图,给出经理的位置,求有多少员工跟经理相邻思路:遍历整个图即可 G - Alice, Bob and Chocolate题意:n个糖果,Alice和Bob一起吃,Alice从左到右吃,Bob从右到左吃,吃每个糖果需要ti的时间,如果两个人同时吃一个时,Bob会让Alice先吃,以体现它的绅士风度。问最后Alice吃了多少个糖果。思路:计算前i个糖果的和sum[i],如果Alice吃到第i个糖果时,sum[i] > sum[n]-sum[i+1]&&sum[i]<sum[n]-sum[i] 时,Alice吃到最多的糖果。 #include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 100000+5;const int MAX = 2147483647;int prime [25] = {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};int arr[N],sum[N];int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);// srand((unsigned)time(NULL)); int n; while(scanf("%d",&n)!=EOF) { sum[0]=0; for(int i=1;i<=n;i++) { scanf("%d",&arr[i]); sum[i] = sum[i-1]+arr[i]; } if(n==1) { cout<<"1 0"<<endl; continue; } for(int i=1;i<n;i++) { if(sum[i]==(sum[n]-sum[i+1])) { cout<<i+1<<" "<<n-(i+1)<<endl; break; }else if(sum[i]>(sum[n]-sum[i+1])) { cout<<i<<" "<<n-i<<endl; break; } } }}