国庆第三次集训: 2012 ACM-ICPC Asia Regional Contest Chengdu Site

A: Extremely easy. It requires you to add all the ASCII value of a string together.

AC Code:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #define ll long long
 9 #define lson l,m,rt<<1;
10 #define rson m+1,r,rt<<1|1;
11 using namespace std;
12 
13 int main(){
14     int T;
15     int kase=0;
16     while(~scanf("%d",&T)){
17         scanf("%d",&T);
18         int MAX=0;
19         char s[1000];
20         for(int i=1;i<=T;i++){
21             scanf("%s",s);
22             int len=strlen(s);
23             int tmp=0;
24             for(int i=0;i<len;i++){
25                 tmp+=s[i];
26             }
27             MAX=max(tmp,MAX);
28         }
29         printf("Case %d: %d
",++kase, MAX);
30     }
31 }
View Code

B: A probability problem. It is actually very easy, I have even listed the correct formula in the contest, however, it seems that p^n is sometimes too small and I started to doubt my intuitive and turned to solve it by dynamic programming. It did not work out. The official solution frustrated me because I was right! The only difference between WA code and AC code is subtle.

WA code:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #define ll long long
 9 #define lson l,m,rt<<1;
10 #define rson m+1,r,rt<<1|1;
11 using namespace std;
12 
13 int main(){
14     int n;double p;int kase=0;
15     while(~scanf("%d%lf",&n,&p)){
16         long double E1=0;
17         long double E2=0;
18         long double temp1=pow(p,n+1);
19         long double temp2=pow(1-p,n+1);
20         
21         long double tmp=1.0*n;
22         for(int i=0;i<n;i++){
23             E1+=tmp;
24             tmp=tmp*(1-p)*(n+i+1)*(n-i-1)/(i+1)/(n-i);
25         }
26         for(int i=1;i<=n+1;i++){
27             E1*=p;
28         }
29         tmp=1.0*n;//printf("%Lf %Lf
",temp1,E1);
30         for(int i=0;i<n;i++){
31             E2+=tmp;
32             tmp=tmp*p*(n-i-1)/(n-i)*(n+i+1)/(i+1);
33         }
34         for(int i=1;i<=n+1;i++){
35             E2*=(1-p);
36         }
37         long double E=E1+E2;//printf("%Lf %Lf
",temp2,E2);
38         printf("Case %d: %Lf
",++kase,E);
39     }
40 }
View Code

AC code:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #define ll long long
 9 #define lson l,m,rt<<1;
10 #define rson m+1,r,rt<<1|1;
11 using namespace std;
12 
13 int main(){
14     int n;double p;int kase=0;
15     while(~scanf("%d%lf",&n,&p)){
16         double E1=0;
17         double E2=0;
18         
19         double tmp=1.0*n;
20         int cnt1=0;
21         for(int i=0;i<n;i++){
22             E1+=tmp;
23             tmp=tmp*(1-p)*(n+i+1)*(n-i-1)/(i+1)/(n-i);
24             while(E1>n){
25                 tmp*=p;
26                 E1*=p;
27                 cnt1++;
28                 if(cnt1>=n+1){
29                     break;
30                 }
31             }
32         }
33         for(int i=1;i<=n+1-cnt1;i++){
34             E1*=p;
35         }
36         tmp=1.0*n;//printf("%Lf %Lf
",temp1,E1);
37         int cnt2=0;
38         for(int i=0;i<n;i++){
39             E2+=tmp;
40             tmp=tmp*p*(n-i-1)/(n-i)*(n+i+1)/(i+1);
41             while(E2>n){
42                 tmp*=(1-p);
43                 E2*=(1-p);
44                 cnt2++;
45                 if(cnt2>=n+1){
46                     break;
47                 }
48             }
49         }
50         for(int i=1;i<=n+1-cnt2;i++){
51             E2*=(1-p);
52         }
53         double E=E1+E2;//printf("%Lf %Lf
",temp2,E2);
54         printf("Case %d: %.6lf
",++kase,E);
55     }
56 }
View Code

I: Extremely easy. DP can solve it elegantly.

AC Code:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #define ll long long
 9 #define lson l,m,rt<<1;
10 #define rson m+1,r,rt<<1|1;
11 using namespace std;
12 
13 const ll mod=1e9+7;
14 ll dp[1005];
15 
16 void fun(int n){
17     dp[n]=(dp[n]+dp[n-1])%mod;
18     for(int i=2;i<=n-1;i++){
19         int tmp=n-i-1;
20         tmp/=i;
21         if(tmp*i==n-i-1){
22             dp[n]=(dp[tmp+1]+dp[n])%mod;
23         }
24     }
25 }
26 
27 void init(){
28     for(int i=1;i<=1000;i++){
29         dp[i]=0;
30     }
31     dp[1]=dp[0]=1;
32     for(int i=2;i<=1000;i++){
33         fun(i);
34     }
35 }
36 
37 int main(){
38     int n,kase=0;
39     init();
40     while(~scanf("%d",&n)){
41         printf("Case %d: %lld
",++kase,dp[n]);
42     }
43 }
View Code

K: A problem of high quality! I firstly thought we can list multiples of N and find if it can satisfy the requirements. Sadly though we cannot know when can we stop searching. The official solution uses a property cleverly: if A=B(mod N), then (A*10+i)=(B*10+i) (mod N), (0<=i<=9). Thus, we need only search those node in N-ring. In other word, if num%N has been visited, we will not search it further. 

AC code:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #define ll long long
 9 #define lson l,m,rt<<1;
10 #define rson m+1,r,rt<<1|1;
11 using namespace std;
12 
13 int pre[10000+5],mod[10000+5],num[10000+5];
14 bool vis[10000+5];
15 int limit[1000];
16 int n,m,kase=0;
17 
18 void print(int v){
19     if(v==-1)return ;
20     print(pre[v]);
21     printf("%d",num[v]);
22     return ;
23 }
24 
25 bool limited(int t){
26     for(int i=0;i<m;i++){
27         if(limit[i]==t)return true;
28     }
29     return false;
30 }
31 
32 void bfs(){
33     for(int i=0;i<n;i++){
34         pre[i]=-1;vis[i]=false;
35     }
36     queue <int> q;
37     for(int i=1;i<=9;i++){
38         if(limited(i))continue;
39         int v=i%n;
40         if(!vis[v]){
41             q.push(v);
42             vis[v]=true;
43             num[v]=i;
44         }
45     }
46     while(!q.empty()){
47         int u=q.front();q.pop();
48         if(u==0){
49             print(u);return ;
50         }
51         for(int i=0;i<=9;i++){
52             if(limited(i))continue;
53             int MOD=(10*u+i)%n;
54             if(!vis[MOD]){
55                 vis[MOD]=true;
56                 q.push(MOD);
57                 pre[MOD]=u;
58                 num[MOD]=i;
59             }
60         }
61     }
62     printf("-1");
63 }
64 
65 int main() {
66     while(~scanf("%d%d",&n,&m)) {
67         for(int i=0; i<m; i++) {
68             scanf("%d",&limit[i]);
69         }
70 
71 
72         
73         printf("Case %d: ",++kase);
74         bfs();
75         printf("
");
76     }
77 }
View Code
一个人要像一支队伍 每一天要像一场战争
原文地址:https://www.cnblogs.com/LiXinze/p/7630022.html