【解题报告】Codeforces Round #301 (Div. 2) 之ABCD
A. Combination Lock
拨密码。。最少次数。。密码最多有1000位。
用字符串存起来,然后每位大的减小的和小的+10减大的,再取较小值加起来就可以了。。。
#include<stdio.h> #include<math.h> #include<string.h> #include<iostream> #include<algorithm> #include<map> #include<set> #include<queue> #include<stack> #define FOR(i,n) for(i=0;i<(n);i++) #define CLR(a) memset(a,0,sizeof(a)) #define CIN(a) scanf("%d",&a) typedef long long ll; using namespace std; char s1[10005],s2[10005]; int main() { int n,ans=0,i; scanf("%d",&n); scanf("%s%s",s1,s2); for(i=0;i<n;i++) { ans+=min(max(s2[i],s1[i])-min(s1[i],s2[i]),min(s2[i],s1[i])+10-max(s1[i],s2[i])); } printf("%d\n",ans); return 0; }
B. School Marks
给定一个数字序列,长度是n,已知其中的前k个数字,求其他数字,满足每个数字最大是p,数字的总和不超过x,这些数的中位数不小于y。
直接贪心即可。
要满足中位数不小于y即必须满足不超过n/2个数小于y。
先统计已知的数中小于y的数的个数,如果已经有超过n/2个就直接NO了。
如果没有n/2个数的话就一直往里面添加1(因为保证和最小)直到刚好是N/2个,然后往里面添加y直到达到n个数。
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<map> 7 #include<set> 8 #include<queue> 9 #include<stack> 10 #define FOR(i,n) for(i=0;i<(n);i++) 11 #define CLR(a) memset(a,0,sizeof(a)) 12 #define CIN(a) scanf("%d",&a) 13 typedef long long ll; 14 using namespace std; 15 int main() 16 { 17 int i,n,k,p,x,y,z,s=0,xiao=0; 18 scanf("%d%d%d%d%d",&n,&k,&p,&x,&y); 19 for(i=0;i<k;i++) 20 { 21 scanf("%d",&z); 22 s+=z; 23 if(z<y) xiao++; 24 } 25 //printf("sum=%d xiao=%d\n",s,xiao); 26 int num=0; 27 int ans[1005]; 28 for(i=k;i<n;i++) 29 { 30 if(xiao<n/2) 31 { 32 ans[num++]=1; 33 s+=1; 34 xiao++; 35 } 36 else if(xiao==n/2) 37 { 38 ans[num++]=y; 39 s+=y; 40 } 41 else {num=-1;break;} 42 } 43 if(s<=x&&num!=-1) 44 { 45 for(i=0;i<num;i++) 46 { 47 if(i!=0) printf(" "); 48 printf("%d",ans[i]); 49 } 50 printf("\n"); 51 } 52 else printf("-1\n"); 53 return 0; 54 }
C. Ice Cave
图中X表示碎冰,点表示完整的冰,每次走过完整的冰时,这块冰就会变成碎冰。走过碎冰之后就会掉下去。。。
给定初始点和目标点,最终要从目标点掉下去。不能原地跳。。。而且初始点一定是X。
直接DFS一遍整张图就可以了。。。走过的点标记为X,没必要回溯。
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<map> 7 #include<set> 8 #include<queue> 9 #include<stack> 10 #define FOR(i,n) for(i=0;i<(n);i++) 11 #define CLR(a) memset(a,0,sizeof(a)) 12 #define CIN(a) scanf("%d",&a) 13 typedef long long ll; 14 using namespace std; 15 char M[505][505]; 16 int x,y,x2,y2; 17 int n,m; 18 int dfs(int x,int y) 19 { 20 if(x>=n||x<0||y>=m||y<0) return 0; 21 if(M[x][y]=='X'&&x==x2-1&&y==y2-1) return 1; 22 if(M[x][y]=='X') return 0; 23 if(M[x][y]=='.') M[x][y]='X'; 24 if(dfs(x-1,y))return 1; 25 if(dfs(x+1,y))return 1; 26 if(dfs(x,y-1))return 1; 27 if(dfs(x,y+1))return 1; 28 return 0; 29 } 30 int main() 31 { 32 int i; 33 scanf("%d%d",&n,&m); 34 for(i=0;i<n;i++) 35 { 36 scanf("%s",M[i]); 37 } 38 scanf("%d%d",&x,&y); 39 scanf("%d%d",&x2,&y2); 40 M[x-1][y-1]='.'; 41 if(dfs(x-1,y-1)){printf("YES\n");} 42 else printf("NO\n"); 43 44 return 0; 45 }
D. Bad Luck Island
有r个石头,s个剪刀,p个布。他们之间随机相遇,如果石头碰见了剪刀,石头就会把剪刀干掉。剪刀碰见布,就会把布干掉。。布碰见石头的话,也会把石头干掉。每一对相遇的概率是相同的,求他们三种最终活下来的概率。
概率DP。。
任意状态(r,s,p)可以变成三种状态(r-1,s,p)、(r,s-1,p)、(r,s,p-1)。
对于状态(a,b,c) 有p(a,b,c)=(a/sum)*(b/(sum-1))+(b/sum)*(a/(sum-1))的概率是a和b相遇(sum=a+b+c)。
即可求出任意状态转换成以上三种状态的概率。
然后状态转移方程就是:
dp{a,b,c} =
p(c,a,b)/sump * dp{a-1,b,c}
+p(a,b,c)/sump * dp{a,b-1,c}
+p(b,c,a)/sump * dp{a,b,c-1}
其中sump =p(a,b,c)+p(b,c,a)+p(c,a,b)
结束。。。
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<map> 7 #include<set> 8 #include<queue> 9 #include<stack> 10 #define FOR(i,n) for(i=0;i<(n);i++) 11 #define CLR(a) memset(a,0,sizeof(a)) 12 #define CIN(a) scanf("%d",&a) 13 typedef long long ll; 14 using namespace std; 15 double dp[105][105][105][2]; 16 double p(int a,int b,int c) 17 { 18 int sum=a+b+c; 19 return (1.0*a/sum)*(1.0*b/(sum-1))+(1.0*b/sum)*(1.0*a/(sum-1)); 20 } 21 double DP(int i,int j,int k,int z) 22 { 23 if(i==0&&j==0) return z==2; 24 if(i==0&&k==0) return z==1; 25 if(k==0&&j==0) return z==0; 26 if(i==0) return z==1; 27 if(j==0) return z==2; 28 if(k==0) return z==0; 29 if(z==2) return 1-dp[i][j][k][0]-dp[i][j][k][1]; 30 return dp[i][j][k][z]; 31 } 32 int main() 33 { 34 int a,b,c,i,j,k; 35 scanf("%d%d%d",&a,&b,&c); 36 for(i=1;i<=a;i++) 37 for(j=1;j<=b;j++) 38 for(k=1;k<=c;k++) 39 { 40 double sump=p(i,j,k)+p(j,k,i)+p(k,i,j); 41 //printf("sump=%lf\n",sump); 42 dp[i][j][k][0]=0; 43 dp[i][j][k][0]+=p(k,i,j)/sump*DP(i-1,j,k,0); 44 dp[i][j][k][0]+=p(i,j,k)/sump*DP(i,j-1,k,0); 45 dp[i][j][k][0]+=p(j,k,i)/sump*DP(i,j,k-1,0); 46 47 dp[i][j][k][1]=0; 48 dp[i][j][k][1]+=p(k,i,j)/sump*DP(i-1,j,k,1); 49 dp[i][j][k][1]+=p(i,j,k)/sump*DP(i,j-1,k,1); 50 dp[i][j][k][1]+=p(j,k,i)/sump*DP(i,j,k-1,1); 51 } 52 printf("%.12lf %.12lf %.12lf\n",DP(a,b,c,0),DP(a,b,c,1),DP(a,b,c,2)); 53 return 0; 54 }