Problem A: 神奇的fans
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 84 Solved: 30 [ ][ ][ ]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
Sample Output
1 #include2 #include 3 #include 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
Problem B:
Time Limit: 2 Sec Memory Limit: 128 MB Submit: 18 Solved: 5 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
HINT
建议先把所有情况都算出来^_^
题目大意:给你一个时间(年月日),你可以将月份+1或将日+1,谁先达到2001.11.4谁赢了,如果你先操作,问你是否必赢。
分析:博弈论,找规律。打表找到的规律是如果(月份+日)为偶数则一定赢,否则输,但有两组特殊数据即11月30与9月30,这两组也为赢。
1 #include2 #include 3 #include 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 else19 printf("YES\n");20 }21 }
Problem C:
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 76 Solved: 13 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
HINT
全部数据n< =50,m< =5
题目大意:上面说的很清楚了
分析:递推,找规律。令f[i]表示i个电站的方案数,那么f[i]=2*f[i-1]-f[i-m-1]
1 #include2 #include 3 #include 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 MB Submit: 58 Solved: 13 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
1 #include2 #include 3 #include 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 20)||(b>20)||(c>20))29 printf("w(%d, %d, %d) = %d\n",a,b,c,f[20][20][20]);30 else31 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 MB Submit: 8 Solved: 7 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
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 #include2 #include 3 #include 4 #include 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 }
为什么上面错误的代码能过呢?因为测试数据只有一组!!!就只有样例,所以下面的神级代码也可以过。=。=明天加数据rejudge吧。
1 #include2 #include 3 using namespace std;4 int main ()5 {6 printf("70\n");7 }
Problem F:
Time Limit: 2 Sec Memory Limit: 128 MB Submit: 15 Solved: 8 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
HINT
题目大意:给你n个数的水晶序列,问你能不能将这些水晶构成两个高度相同的塔,如果可以输出最大的塔高。
分析:动态规划,dp[i][j]表示第一座塔高i,第二座高j能不能达到,(1为可以,0为不可以)
那么就是变形0-1背包了,一个水晶可以加入第一座塔,也可以加入第二座,或者不加。枚举每个水晶,记录每次可能的情况,最后搜索最大的i使dp[i][i]=1就是答案,如果没有则输出Impossible。
注意点:初始化为dp[0][0]=1,其余为0,但最后如果有(0,0)的应该是输出Impossible的。
1 #include2 #include 3 #include 4 #include 5 #define maxlen 2100 6 #define INF 0x7fffff 7 using namespace std; 8 bool dp[maxlen][maxlen]; 9 int num[200];10 int n;11 int main()12 {13 while(scanf("%d",&n)!=EOF)14 {15 memset(dp,0,sizeof(dp));16 for(int i=0; i =0; --j)22 {23 for(int k=1010; k>=0; --k)24 {25 if(dp[j][k]==true)26 {27 if(j+num[i]<=1010)28 dp[j+num[i]][k]=true;29 if (k+num[i]<=1010)30 dp[j][k+num[i]]=true;31 }32 }33 }34 }35 int flag=0;36 for(int i=1010; i>0; --i)37 {38 if(dp[i][i]==true)39 {40 flag=1;41 printf("%d\n",i);42 break;43 }44 }45 if(!flag)46 printf("Impossible\n");47 }48 }
Problem G:
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 10 Solved: 2 [ ][ ][ ]Description
Input
Output
Sample Input
Sample Output
1 #include2 #include 3 #include 4 using namespace std; 5 int l,a[102],s,t,n; 6 int dp[3300000],d[3300000]; 7 int main() 8 { 9 scanf("%d%d%d%d",&l,&s,&t,&n);10 for(int i=1; i<=n; ++i)11 scanf("%d",&a[i]);12 int num;13 if(s==t)14 {15 num=0;16 for(int i=1; i<=n; i++)17 if(a[i]%s==0) num++;18 printf("%d\n",num);19 }20 else21 {22 int tmp;23 sort(a+1,a+n+1);24 a[n+1]=l;25 for(int i=1; i<=n; ++i)26 {27 if(a[i+1]-a[i]>100)28 a[i+1]=a[i]+(a[i+1]-a[i])%100;29 }30 l=a[n+1];31 for(int i=1; i<=n; ++i)32 d[a[i]]=1;33 for(int i=1; i<=l+t; ++i)34 dp[i]=0xFFFFFFF;35 for(int i=s; i<=l+t; ++i)36 {37 for(int j=s; j<=t; ++j)38 {39 if(i>=j&&dp[i]>dp[i-j]+d[i])40 dp[i]=dp[i-j]+d[i];41 }42 }43 num=0xFFFFFFF;44 for(int i=l; i<=l+t; ++i)45 num=min(num,dp[i]);46 printf("%d\n",num);47 }48 return 0;49 }
Problem H: 过河卒
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 42 Solved: 9 [ ][ ][ ]Description
如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C<>A,同时C<>B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。
Input
键盘输入
B点的坐标(n,m)以及对方马的坐标(X,Y){不用判错}Output
屏幕输出
一个整数(路径的条数)。Sample Input
Sample Output
HINT
题目大意:给你一个n*m个棋盘。卒只能向下或向右走,有一匹马在(x,y)马边上(9个)的的位置不能走,问从(0,0)到(n,m)有多少种走法。
分析:动态规划。令dp[i][j]表示(0,0)到(i,j)的路径数,那么方程就是dp[i][j]=dp[i-1][j]+dp[i][j-1]。
1 #include2 #include 3 #include 4 #define maxlen 30 5 #define INF -100000 6 using namespace std; 7 long long dp[30][30],visited[30][30]; 8 int n,m,x,y; 9 int xx[]= {-2,-2,-1,-1, 1, 1, 2, 2};10 int yy[]= {-1, 1,-2, 2,-2, 2,-1, 1};11 int xxx[]={ 0,-1};12 int yyy[]={-1,0};13 int main ()14 {15 while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF)16 {17 memset(dp,0,sizeof(dp));18 dp[0][0]=1;19 memset(visited,0,sizeof(visited));20 visited[x][y]=visited[0][0]=1;21 for(int i=0; i<8; ++i)22 {23 int nextx=x+xx[i];24 int nexty=y+yy[i];25 visited[nextx][nexty]=1;26 }27 for(int i=0; i<=n; ++i)28 {29 for(int j=0; j<=m; ++j)30 {31 for(int k=0;k<2;++k)32 if(!visited[i][j])33 dp[i][j]+=dp[i+xxx[k]][j+yyy[k]];34 }35 }36 printf("%lld\n",dp[n][m]);37 }38 }