话说没有完成任务就不要悠闲地去睡觉啊~
Problem A: 神奇的fans
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 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
Sample Output
HINT
#include <iostream>
#include<algorithm>
using namespace std;
int a[100];
int cmp(int a,int b)
{
return a>b;
}
int main()
{
int n,m,flag;
cin>>n;
while(n--){
cin>>m;
flag=1;
for(int i=0;i<m;i++)
cin>>a[i];
sort(a,a+m,cmp); //从小到大排个序
for(int i=0;i<m-2;i++){
if(2*a[i+1]!=a[i]+a[i+2]){ //判断等差中项是否相等
flag=0;
cout<<"no"<<endl;
break;
}
}
if(flag)
cout<<"yes"<<endl;
}
return 0;
}
Problem B: 伊甸园日历游戏
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 18 Solved: 5
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
HINT
建议先把所有情况都算出来^_^
//vijos-p1004
#include <iostream>
using namespace std;
int main()
{
int t,x,y,z;
cin>>t;
while(t--){
cin>>x>>y>>z;
if((y==9&&z==30)||(y==11&&z==30))
cout<<"YES"<<endl;
else if((y+z)&1)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}
Problem C: 核电站问题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 76 Solved: 13
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
HINT
全部数据n< =50,m< =5
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
long long f[60];
int main()
{
int n,m;
while(cin>>n>>m){
f[4]=f[5]=1;
for(int i=6;i<n+6;i++)
f[i]=2*f[i-1]-f[i-m-1];
printf("%lld\n",f[n+5]);
}
return 0;
}
Problem D: Function(Function(F...
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 58 Solved: 13
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
#include <iostream>
#include <stdio.h>
#include<string.h>
using namespace std;
#define N -999999
int vis[25][25][25];
long long w(int a,int b,int c)
{
if(a<=0||b<=0||c<=0)
return 1;
else if(a>20||b>20||c>20)
return w(20,20,20);
if(vis[a][b][c]!=N)
return vis[a][b][c];
else if(a<b&&b<c){
vis[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
return vis[a][b][c];
}
else{
vis[a][b][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);
return vis[a][b][c];
}
}
int main()
{
int a,b,c;
long long temp;
while(cin>>a>>b>>c){
if(a==-1&&b==-1&&c==-1)
break;
for(int i=0;i<=20;i++)
for(int j=0;j<=20;j++)
for(int k=0;k<=20;k++)
vis[i][j][k]=N;
printf("w(%d, %d, %d) = %d\n",a,b,c,w(a,b,c));
}
return 0;
}
way2:
#include <iostream>
#include <stdio.h>
#include<string.h>
using namespace std;
#define N -999999
int f[25][25][25];
int main()
{
int a,b,c;
for(int i=0;i<=20;i++){
for(int j=0;j<=20;j++){
for(int k=0;k<=20;k++){
if((i==0)||(j==0)||(k==0)) f[i][j][k]=1;
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];
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];
}
}
}
while(cin>>a>>b>>c){
if(a==-1&&b==-1&&c==-1)
break;
if((a<=0)||(b<=0)||(c<=0))
printf("w(%d, %d, %d) = 1\n",a,b,c);
else if((a>20)||(b>20)||(c>20) )
printf("w(%d, %d, %d) = %d\n",a,b,c,f[20][20][20]);
else
printf("w(%d, %d, %d) = %d\n",a,b,c,f[a][b][c]);
}
return 0;
}
Problem E: VIJOS-P1292
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 9 Solved: 8
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
HINT
这道题根本就没往复杂处想,拿来就直接做了,自己的思路是先求出出发站与到达站之间的距离,然后按照他所在的范围一次减去L1、2、3,同时加上相应的票价。同学用的是DP,暂时没弄明白,再去讨教讨教。话说因为之前能过是因为只有一组数据,惭愧!Problem F: 搭建双塔
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 15 Solved: 8
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
HINT
分析:DP,dp[i][j](两座塔的高度i,j)如果为1则存在,若为0则不存在;最后找dp[i][j]最大的,若没有则输出 “Impossible”;#include <iostream>
#include<string.h>
using namespace std;
int h[105];
int dp[2010][2010];
int main()
{
int n,sum=0,flag;
while(cin>>n){
flag=0;
for(int i=0;i<n;i++)
cin>>h[i];
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=0;i<n;i++)
for(int j=1001;j>=0;j--)
for(int k=1001;k>=0;k--){
if(dp[j][k]){
if(j+h[i]<=1001)
dp[j+h[i]][k]=1;
if(k+h[i]<=1001)
dp[j][k+h[i]]=1;
}
}
for(int i=1001;i>0;i--)
if(dp[i][i]){
cout<<i<<endl;
flag=1;
break;
}
if(!flag)
cout<<"Impossible"<<endl;
}
return 0;
}
Problem G: 过河
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 10 Solved: 2
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
Sample Output
dp[i]=dp[i-j]+flag[i](s<=j<=t,flag[i]为i点有无石头)
//VIJOS-P1002
#include <iostream>
#include <algorithm>
#define N 3200000
#define MAX 999
using namespace std;
int dp[N],flag[N];
int s,t,m,a[110];
int GCD(int a,int b)
{
return b==0?a:GCD(b,a%b);
}
int main()
{
int l,count;
cin>>l>>s>>t>>m;
for(int i=1;i<=m;i++)
cin>>a[i];
int lcm=1;
for(int i=2;i<=10;i++)
lcm=lcm*i/GCD(lcm,i);
sort(a+1,a+m+1);
a[m+1]=l; //跳出
for(int i=1;i<=m;i++)
if(a[i+1]-a[i]>lcm)
a[i+1]=a[i]+(a[i+1]-a[i])%lcm; //压缩
l=a[m+1]; //更新l
for(int i=1;i<=m;i++) flag[a[i]]=1;
for(int i=1;i<=l+t;i++) dp[i]=MAX; //可跳过l+t
for(int i=1;i<=l+t;i++)
for(int j=s;j<=t;j++)
if(i>=j&&dp[i]>dp[i-j]+flag[i])
dp[i]=dp[i-j]+flag[i];
count=MAX;
for(int i=l;i<=l+t;i++)
if(count>dp[i])
count=dp[i];
cout<<count<<endl;
return 0;
}
Problem H: 过河卒
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 69 Solved: 14
[ Submit][ Status][ Web Board]
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
话说这道题也忒wired了,交了n次都不过,最好还是仰仗大神了。思路倒是挺清楚的,因为不用判断错所以就简化了不少#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long dp[30][30],vis[30][30];
int n,m,x,y;
int main ()
{
while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
memset(vis,0,sizeof(vis));
vis[0][0]=1;
vis[x][y]=1; vis[x+2][y+1]=1; vis[x+1][y+2]=1; //马控制点
vis[x-2][y-1]=1; vis[x-1][y-2]=1; vis[x+1][y-2]=1;
vis[x+2][y-1]=1; vis[x-1][y+2]=1; vis[x-2][y+1]=1;
for(int i=0; i<=n; ++i)
{
for(int j=0; j<=m; ++j)
{
if(!vis[i][j]) //如果不是马控制点
dp[i][j]=(dp[i-1][j]+dp[i][j-1]);
}
}
printf("%lld\n",dp[n][m]);
}
}