CF 191 总结

A. Flipping Game

链接:http://codeforces.com/contest/327/problem/A

题意:从 i 到 j 翻转一次使得 1 的 个数最多~

直接暴力搞~

 1 #include 
 2 #include 
 3 #include 
 4 using namespace std;
 5 int N;
 6 int a[105], b[105];
 7 int main( )
 8 {
 9     while(scanf("%d", &N)!= EOF){
10         for(int i=0; i i){
11             scanf("%d", &a[i]);
12             b[i]=a[i];
13         }
14         int ans=-1;
15         for( int i=0; i i ){
16             for( int j=i; j j ){
17                 for( int k=i; k<=j ; ++ k){
18                     b[k]=1-a[k];
19                 }
20                 int t=0;
21                 for( int k=0; k k ){
22                     if(b[k]) t++;
23                     ans=ans>t?ans:t;
24                     b[k]=a[k];
25                 }    
26             }
27         }
28         printf("%d\n", ans);
29     }
30     return 0;
31 }
View Code

B. Hungry Sequence

链接:http://codeforces.com/contest/327/problem/B

题意:生成一个排列, 如果 i < j  那么 p[i]

数据范围:n < =10^5 ~ 直接生成10^5个素数即可~

 1 #include 
 2 #include 
 3 #include 
 4 using namespace std;
 5 int a[2000000], p[200000];
 6 void getp( )
 7 {
 8     for( int i=3; i<=10000; i+=2 ){
 9         if( !a[i] ){
10             for( int j=i*i; j<2000000; j+=i ){
11                 a[j]=1;
12             }
13         }
14     }   
15     p[0]=2;
16     int k=1;
17     for(int i=3; i<2000000; i+=2){
18         if( !a[i] )p[k++]=i;
19     }
20 }
21 int main( )
22 {
23     getp( );
24     int N;
25     while( scanf("%d", &N)!= EOF ){
26         for ( int i=0; i i ){
27             printf(i!=N-1?"%d ":"%d\n", p[i]);
28         }
29     }
30     return 0;
31 }
View Code

C. Magic Five

链接:http://codeforces.com/contest/327/problem/C

题意:给定字符串 s 和 整数 k 表示有 k 个 s 重复组成的字符串 S‘ 要从中截取一些,使得剩下的字符串能表示的整数能整除5~

思路: 等比数列求和;

例如求sum=2^1+2^2+2^3+2^4+2^5+2^6+2^7 .. + 2^n~

公式就为 若n%2==0     T(n)=T(n/2)+T(n/2)*2^(n/2);

               若n%2==1     T(n)=T(n/2)+T(n/2)*2^(n/2)+ 2^n;

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 using namespace std;
 6 typedef __int64 LL;
 7 const LL Mod=1e9+7;
 8 char s[100000];
 9 LL m, k, ans, x;
10 LL P_M(int x, int n )
11 {
12     LL rec=1, t=x;
13     while( n ){
14         if(n&1){
15             rec*=t;
16             rec%=Mod;
17         }
18         t*=t;
19         t%=Mod;
20         n>>=1;
21     }
22     return rec; 
23 }
24 LL Sum( int x, int n )
25 {
26     if( n==1 )
27         return x;
28     LL t=Sum( x, n/2 );
29     t=( t+t*P_M(m, n/2))%Mod;// m为公比; 
30     if( n&1 ) t=(t+P_M( m, n-1)*x)%Mod;// 加上an
31     return t;
32 }
33 
34 int main( )
35 {
36     while( scanf("%s%I64d", s, &k)!= EOF ){
37         int l=strlen ( s );
38         m=P_M(2, l), x=1;
39         for( int i=0; i i ){
40             if( s[i]=='5' || s[i]=='0' ){
41                 ans=(ans+x)%Mod;
42             }
43             x=(x*2)%Mod;
44         }
45         ans=Sum( ans, k );
46         printf("%I64d\n", ans);
47     }
48     return 0;
49 }
View Code

D. Block Tower

链接:http://codeforces.com/contest/327/problem/D

题意:堆房子,要求人最多,堆红色的时候,要求边上一定要有蓝色的~

思路:只要总数最大,过程不做要求~所以可以把每一块先变成蓝色, 再逐渐变成红色~

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 using namespace std;
 7 #define lega(x, a) ((x)<=(a) && 0 <(x))
 8 char s[505][505];
 9 bool vi[505][505];
10 int N, M, ans;
11 struct Node 
12 {
13     int x, y;
14     bool f;
15     Node( ){}
16     Node(int _x, int _y, bool _f){
17         x=_x, y=_y, f=_f;
18     }
19 }p;
20 stacksn;
21 const int xx[4]={0,0,1,-1};
22 const int yy[4]={1,-1,0,0};
23 void DFS( int x, int y )
24 {
25     int _x,_y;
26     for( int i=0; i<4; ++ i ){
27         _x=x+xx[i], _y=y+yy[i];
28         if( lega(_x,N) && lega(_y, M) && !vi[_x][_y] ){
29             vi[_x][_y]=1;
30             sn.push(Node( _x,_y, false ));
31             DFS( _x, _y );
32         }
33     }
34 }
35 
36 int main( )
37 {
38     while( scanf("%d%d", &N, &M)!= EOF ){
39         for( int i=1;i<=N; ++ i ){
40             scanf("%s", s[i]+1);
41         }
42         while(!sn.empty()){
43             sn.pop( );
44         }
45         memset(vi, 0, sizeof vi);
46         ans=0;
47         for( int i=1; i<=N; ++ i ){
48             for( int j=1; j<=M; ++ j ){
49                 if( !vi[i][j]&&s[i][j]=='.' ){
50                     vi[i][j]=1;
51                     sn.push(Node(i, j, true));
52                     ans-=2; // 最后一个不能被拆, 减少两次操作 
53                     DFS(i, j);            }
54             }
55         }
56         ans+=3*sn.size( ); 
57         printf("%d\n", ans);
58         for( int i=1; i<=N; ++ i ){
59             for(int j=1; j<=M; ++ j){
60                 if( vi[i][j] ){
61                     printf("B %d %d\n", i, j);
62                 }
63             }
64         }
65         while( !sn.empty( ) ){
66             p=sn.top( );
67             sn.pop( );
68             if( !p.f ){// 只要求建红色的时候边上有蓝色的, 并不是要求最后的状态是红色边上有蓝色 
69                 printf("D %d %d\n", p.x, p.y);
70                 printf("R %d %d\n", p.x, p.y);
71             }
72         }
73     }
74     return 0;
75 }
View Code

E. Axis Walking

链接:http://codeforces.com/contest/327/problem/E

题意: 有两个集合 A, K, 要求 A 集合的一个排列, 其前缀和不等于 k 中任意一个元素, 求有多少个排列~

思路: 设 A 集合的元素为 a1, a2, a3~~~an, 用一整数 x 的对应位表示~

DP方程,i表示选择从1–n中选择 i 个数字,dp[i][n]表示可行解
dp[0][n]=1,表示初始状态.
如x的二进制位为1111。分别表示有a1,a2,a3,a4 ,四个数~

则有 dp[1111]=dp1110]+dp[1101]+dp[1011]+dp[0111]~

 1 #include 
 2 #include 
 3 #include 
 4 #define lowbit(x) ((x)&(-x))
 5 using namespace std;
 6 
 7 const int Mod=1e9+7;
 8 int N, K, a[30];
 9 int b[(1<<24)+10], dp[(1<<24)+10];
10 int main( )
11 {
12     while( scanf("%d", &N)!= EOF ){
13         int kk[2]={0};
14         for( int i=0; i i ){
15             scanf("%d", &a[i]);
16             b[1<a[i];
17         }
18         scanf("%d", &K);
19         for( int i=0; i i ){
20             scanf("%d", &kk[i]);
21         }
22         dp[0]=1, b[0]=0;
23         for( int i=1; i<(1< i ){
24             b[i]=b[i-lowbit(i)]+b[lowbit(i)];
25             if(b[i]==kk[0] || b[i]==kk[1]){
26                 continue;
27             }
28             int temp=0;
29             for( int j=i; j; j-=lowbit(j) ){
30                 temp+=dp[i-lowbit(j)];
31                 while( temp>=Mod )temp-=Mod;
32             }
33             dp[i]=temp;    
34         }
35         printf("%d\n", dp[(1<1]);
36     }
37     return 0;
38 }
View Code

 

 

 

转载于:https://www.cnblogs.com/jian1573/p/3198312.html

你可能感兴趣的:(CF 191 总结)