Problem A: 神奇的fans
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 84 Solved: 30
[Submit][Status][Web Board]
Description
传说fans是一个数学天才。在他五岁那年,从一堆数字卡片中选出了4张 卡片:5,7,6,8。这4个数字有什么神秘之处呢?如果把这4张卡片自左往右的排成:5,6,7,8。你就会发现:原来这4个数字构成了等差数列!当年 fans选出了n组卡片,据说都能够构成等差数列。但是事实真的是这样吗?fans真的有这么神奇吗? n组数据就是fans选出的n组卡片,请你判断每一组卡片是否能构成等差数列.
Input
第一个数为数据的组数n,表示后面有n行,每行中的第一个数为该组数据的元素个数m(1≤m≤100),其后是m个正整数(不会超出int的表示范围)。
Output
如果能够构成等差数列,输出“yes”,否则输出“no”。
Sample Input
2
4 5 7 6 8
8 1 7 3 2 8 12 78 3
Sample Output
yes
no
题目大意:给你n个数,问是否可以构成等差数列
分析:水题,sort后判断一下是不是等差即可
1 #include <iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 int n,t; 6 int a[110]; 7 int main() 8 { 9 scanf("%d", &t); 10 while(t--) 11 { 12 scanf("%d", &n); 13 for (int i=0; i<n; i++) 14 scanf("%d",&a[i]); 15 sort(a,a+n); 16 if (n<=2) 17 { 18 printf("yes\n"); 19 continue; 20 } 21 int flag=1; 22 for(int i=1; i<n-1; i++) 23 { 24 if((a[i+1]-a[i])!=(a[1]-a[0])) 25 { 26 flag=0; 27 break; 28 } 29 } 30 if (flag) 31 printf("yes\n"); 32 else 33 printf("no\n"); 34 } 35 return 0; 36 }
Problem B: 伊甸园日历游戏
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 18 Solved: 5
[Submit][Status][Web Board]
Description
Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来。然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到1900.1.2 2 : 把月份加1,例如:1900.1.1变到1900.2.1 其中如果天数超过应有天数则日期变更到下个月的第1天。月份超过12则变到下一年的1月。而且进行操作二的时候,如果有这样的日期:1900.1.31,则变成了1900.2.31,这样的操作是非法的,我们不允许这样做。而且所有的操作均要考虑历法和闰年的规定。 谁先将日期变到2001.11.4谁就赢了。 每次游戏都是Adam先操作,问他有没有必胜策略?
Input
一个测试点。多组数据。 第一行为数据组数。 接下来一行X Y Z表示X年Y月Z日
Output
输出“YES”or“NO”表示亚当是否有必胜策略。
Sample Input
3
2001 11 3
2001 11 2
2001 10 3
Sample Output
YES
NO
NO
HINT
建议先把所有情况都算出来^_^
题目大意:给你一个时间(年月日),你可以将月份+1或将日+1,谁先达到2001.11.4谁赢了,如果你先操作,问你是否必赢。
分析:博弈论,找规律。打表找到的规律是如果(月份+日)为偶数则一定赢,否则输,但有两组特殊数据即11月30与9月30,这两组也为赢。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int t,y,m,d; 6 int main () 7 { 8 scanf("%d",&t); 9 while(t--) 10 { 11 scanf("%d%d%d",&y,&m,&d); 12 if (m==9&&d==30) 13 printf("YES\n"); 14 else if(m==11&&d==30) 15 printf("YES\n"); 16 else if((m+d)&1) 17 printf("NO\n"); 18 else 19 printf("YES\n"); 20 } 21 }
Problem C: 核电站问题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 76 Solved: 13
[Submit][Status][Web Board]
Description
一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。 现在,请你计算:对于给定的N和M,求不发生爆炸的放置核物质的方案总数。
Input
输入文件只有一行,两个正整数N,M。
Output
输出文件只有一个正整数,表示方案总数。
Sample Input
4 3
Sample Output
13
HINT
全部数据n< =50,m< =5
题目大意:上面说的很清楚了
分析:递推,找规律。令f[i]表示i个电站的方案数,那么f[i]=2*f[i-1]-f[i-m-1]
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 long long s[60]; 6 int main () 7 { 8 int n,m; 9 while(scanf("%d%d",&n,&m)!=EOF) 10 { 11 s[4]=s[5]=1; 12 for(int i=6; i<=n+6; ++i) 13 { 14 s[i]=2*s[i-1]-s[i-m-1]; 15 } 16 printf("%lld\n",s[n+5]); 17 } 18 }
Problem D: Function(Function(F...
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 58 Solved: 13
[Submit][Status][Web Board]
Description
对于一个递归函数w(a,b,c) 如果a< =0 or b< =0 or c< =0就返回值1. 如果a> 20 or b> 20 or c> 20就返回w(20,20,20) 如果a< b并且b< c 就返回w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c) 其它别的情况就返回w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1) 这是个简单的递归函数,但实现起来可能会有些问题。当a,b,c均为15时,调用的次数将非常的多。你要想个办法才行.
Input
会有若干行. 并以-1,-1,-1结束.
Output
输出若干行
Sample Input
1 1 1
2 2 2
-1 -1 -1
Sample Output
w(1, 1, 1) = 2
w(2, 2, 2) = 4
题目大意:给了你一个递归式,要求你求答案。
分析:记忆化搜索或递推。
1、如果直接写成递归形式会超时(这是一定的),所以采用数组保存每一次搜索到的数据,下次再搜索到这个位置时就直接返回不在递归下去。
2、直接写成递推形式,两者没什么太大区别。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define maxlen 30 5 using namespace std; 6 int f[maxlen][maxlen][maxlen]; 7 int main() 8 { 9 int a,b,c; 10 for (int i=0; i<=20; i++) 11 { 12 for (int j=0; j<=20; j++) 13 { 14 for (int k=0; k<=20; k++) 15 { 16 if ((i==0)||(j==0)||(k==0)) f[i][j][k]=1; 17 else if ((i<j)&&(j<k)) f[i][j][k]=f[i][j][k-1]+f[i][j-1][k-1]-f[i][j-1][k]; 18 else f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k]+f[i-1][j][k-1]-f[i-1][j-1][k-1]; 19 } 20 } 21 } 22 while (scanf("%d%d%d",&a,&b,&c)) 23 { 24 if(a==-1&&b==-1&&c==-1) 25 break; 26 if ((a<=0)||(b<=0)||(c<=0)) 27 printf("w(%d, %d, %d) = 1\n",a,b,c); 28 else if ((a>20)||(b>20)||(c>20)) 29 printf("w(%d, %d, %d) = %d\n",a,b,c,f[20][20][20]); 30 else 31 printf("w(%d, %d, %d) = %d\n",a,b,c,f[a][b][c]); 32 } 33 return (0); 34 }
Problem E: 火车票
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 8 Solved: 7
[Submit][Status][Web Board]
Description
一个铁路线上有n(2< =n< =10000)个火车站,每个火车站到该线路的首发火车站距离都是已知的。任意两站之间的票价如下表所示: 站之间的距离X 票价 0< X< =L1 C1 L1< X< =L2 C2 L2< X< =L3 C3 其中L1,L2,L3,C1,C2,C3都是已知的正整数,且(1 < = L1 < L2 < L3 < = 10^9, 1 < = C1 < C2 < C3 < = 10^9)。显然若两站之间的距离大于L3,那么从一站到另一站至少要买两张票。注意:每一张票在使用时只能从一站开始到另一站结束。 现在需要你对于给定的线路,求出从该线路上的站A到站B的最少票价。你能做到吗?
Input
输入文件的第一行为6个整数, L1, L2, L3, C1, C2, C3 (1 < = L1 < L2 < L3 < = 10^9, 1 < = C1 < C2 < C3 < = 10^9) ,这些整数由空格隔开.第二行为火车站的数量N (2 < = N < = 10000).第三行为两个不同的整数A、B,由空格隔开。接下来的 N-1 行包含从第一站到其他站之间的距离.这些距离按照增长的顺序被设置为不同的正整数。相邻两站之间的距离不超过L3. 两个给定火车站之间行程花费的最小值不超过10^9,而且任意两站之间距离不超过 10^9。
Output
输出文件中只有一个数字,表示从A到B要花费的最小值.
Sample Input
3 6 8 20 30 40
7
2 6
3
7
8
13
15
23
Sample Output
70
HINT
题目大意:给你三种距离对应的票价,然后给你n个站之间的距离,问你从站a->站b最少的费用是多少。
分析:动态规划。令dp[i]表示第a个站到第i个站的最小费用,那么有三种情况,即分别买三种车票(如果可以)。。。
所以状态转移方程为dp[i]=min{dp[j]+c1,dp[k]+c2,dp[l]+c3},j,k,l分别表示买相应车票能够到的最远的车站编号。
这个程序有点小问题,TLE,但是却过了。为什么能过呢?稍后解答
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #define maxlen 10010 6 #define INF 0x3fffffff 7 using namespace std; 8 long long dp[maxlen],dist[maxlen]; 9 int l1,l2,l3,c1,c2,c3; 10 int n,a,b; 11 int main () 12 { 13 while(scanf("%d%d%d%d%d%d",&l1,&l2,&l3,&c1,&c2,&c3)!=EOF) 14 { 15 scanf("%d",&n); 16 scanf("%d%d",&a,&b); 17 dist[1]=0; 18 for(int i=2;i<=n;++i) 19 scanf("%lld",&dist[i]); 20 for(int i=0;i<=n;++i) 21 dp[i]=INF; 22 dp[a]=0; 23 for(int i=a;i<=b;++i) 24 { 25 for(int j=a;j<=b;++j) 26 { 27 if(abs(dist[i]-dist[j])<=l1) 28 dp[i]=min(dp[i],dp[j]+c1); 29 else if(abs(dist[i]-dist[j]<=l2)) 30 dp[i]=min(dp[i],dp[j]+c2); 31 else if(abs(dist[i]-dist[j]<=l3)) 32 dp[i]=min(dp[i],dp[j]+c3); 33 } 34 } 35 printf("%lld\n",dp[b]); 36 } 37 }