两道枚举题

http://acm.pku.edu.cn/JudgeOnline/problem?id=2965

我用纯枚举做的,216,用了500多ms

 

code1
   
     
1 // 579MS 2010-05-21 13:57:29
2   #include < stdio.h >
3 #include < string .h >
4
5   const int MK = 1 << 16 ;
6   // 状态转换
7   int swt[ 20 ] = { 0 ,
8 0xf888 , 0xf444 , 0xf222 , 0xf111 ,
9 0x8f88 , 0x4f44 , 0x2f22 , 0x1f11 ,
10 0x88f8 , 0x44f4 , 0x22f2 , 0x11f1 ,
11 0x888f , 0x444f , 0x222f , 0x111f
12 };
13
14   int main()
15 {
16 char ch0[ 20 ], ch1[ 10 ];
17 int I, K, M;
18 int em = 0 , min, hd;
19 while (gets(ch1)) {
20 strcpy(ch0, ch1);
21 I = 3 ;
22 while (I -- ) {
23 gets(ch1);
24 strcat(ch0, ch1);
25 }
26 int stu0, stu1;
27 stu0 = 0 ;
28 // 生成初始状态
29   for (I = 0 ; I < 16 ; I ++ ) {
30 if (ch0[I] == ' + ' ) stu0 |= 1 << ( 16 - I - 1 );
31 }
32 min = 0xffffff ;
33 // 枚举
34   for (em = 0 ; em < MK; em ++ ) {
35 int cnt = 0 ;
36 stu1 = stu0;
37 for (I = 0 ; I < 16 ; I ++ ) {
38 if ( ( 1 << I) & em ) {
39 cnt ++ ;
40 stu1 ^= swt[I + 1 ];
41 }
42 }
43 // stu1 = 0 满足条件
44   if ( ! stu1) {
45 if (cnt < min) { min = cnt; hd = em; }
46 }
47 }
48 printf( " %d\n " , min);
49 for (I = 0 ; I < 16 ; I ++ ) {
50 if ( ( 1 << I) & hd ) {
51 printf( " %d %d\n " , I / 4 + 1 , I % 4 + 1 );
52 }
53 }
54 }
55 return 0 ;
56 }
57  

 

再看看No.1的题解

 

代码
   
     
1 可以,下面是我两次AC的代码,前一次算是证明吧
2 Problem: 2965 User: huicpc39
3 Memory: 24K Time: 45MS
4 Language: C Result: Accepted
5
6 Source Code
7 #include < stdio.h >
8   int main()
9 { char s[ 5 ]; int i,j,k,st[ 4 ][ 4 ];
10   for (i = 0 ;i < 4 ; ++ i) for (j = 0 ;j < 4 ; ++ j)st[i][j] = 0 ;
11   for (i = 0 ;i < 4 ; ++ i)
12 {scanf( " %s " ,s);
13   for (j = 0 ;j < 4 ; ++ j) if (s[j] == ' + ' )
14 {st[i][j] ++ ;
15   for (k = 0 ;k < 4 ; ++ k)st[k][j] ++ ;
16   for (k = 0 ;k < 4 ; ++ k)st[i][k] ++ ;}}
17   for (i = 0 ;i < 4 ; ++ i) for (j = 0 ;j < 4 ; ++ j)st[i][j] %= 2 ;
18   for (i = j = 0 ;i < 4 ; ++ i) for (k = 0 ;k < 4 ; ++ k) if (st[i][k])j ++ ;
19 printf( " %d\n " ,j);
20   for (i = 0 ;i < 4 ; ++ i) for (j = 0 ;j < 4 ; ++ j) if (st[i][j])printf( " %d %d\n " ,i + 1 ,j + 1 );
21 }
22 按照以上思路,直接生成结果。
23 Source Code
24
25 Problem: 2965 User: huicpc39
26 Memory: 16K Time: 0MS
27 Language: C Result: Accepted
28
29 Source Code
30 #include < stdio.h >
31 int s[ 16 ] = { 0x111f , 0x222f , 0x444f , 0x888f , 0x11f1 , 0x22f2 , 0x44f4 , 0x88f8 ,
32 0x1f11 , 0x2f22 , 0x4f44 , 0x8f88 , 0xf111 , 0xf222 , 0xf444 , 0xf888 };
33 int main()
34 { char c; int i,n,j;
35 n = i = j = 0 ;
36 while ((c = getchar()) != EOF)
37 if (c != 10 ) if (c == ' + ' )n ^= s[i ++ ]; else ++ i;
38 for (i = 0 ;i < 16 ; ++ i) if (n & ( 1 << i)) ++ j;printf( " %d\n " ,j);
39 for (i = 0 ;i < 16 ; ++ i) if (n & ( 1 << i))printf( " %d %d\n " ,i / 4 + 1 ,i % 4 + 1 );}
40

 

 

http://acm.pku.edu.cn/JudgeOnline/problem?id=1753

枚举第1行的操作,24

然后操作第2-4行,使第i行的操作让i-1行满足全黑或全白。

求出最小的操作数。

 

code3
   
     
1 // 124K 16MS 2010-05-21 10:50:18
2 // Type:枚举
3 #include < stdio.h >
4 #include < string .h >
5
6 int tsf[ 20 ]; // 保存2^i
7 const int MK = 0xf ; // 枚举次数
8 // 对每个位置的操作
9 int swt[ 20 ] = { 0 ,
10 0x13 , 0x27 , 0x4E , 0x8C ,
11 0x131 , 0x272 , 0x4E4 , 0x8C8 ,
12 0x1310 , 0x2720 , 0x4E40 , 0x8C80 ,
13 0x3100 , 0x7200 , 0xE400 , 0xC800
14 };
15
16 void init()
17 {
18 int i;
19 tsf[ 1 ] = 1 ;
20 for (i = 2 ; i <= 16 ; i ++ ) tsf[i] = tsf[i - 1 ] << 1 ;
21 }
22
23 void Enum( int stu0, int & min)
24 {
25 int I, K, em, cnt, stu;
26 for (em = 0 ; em <= MK; em ++ ) {
27 cnt = 0 ;
28 stu = stu0;
29 // 对第1行的操作
30 for (I = 1 ; I <= 4 ; I ++ ) {
31 if ( em & tsf[I] ) {
32 stu ^= swt[I + 12 ];
33 cnt ++ ;
34 }
35 }
36 // 对2-4行的操作
37 for (I = 16 ; I > 4 ; I -- ) {
38 if ( stu & tsf[I] ) {
39 stu ^= swt[I - 4 ];
40 cnt ++ ;
41 }
42 }
43 if ( ! stu) {
44 if (min == - 1 ) min = cnt;
45 else if (cnt < min) min = cnt;
46 }
47 }
48 }
49
50 int main()
51 {
52 init();
53 char ch0[ 20 ], ch1[ 20 ];
54 int I, K;
55 int stu1, stu2; // 两个不同的状态
56 int min1, min2;
57 while (gets(ch1)) {
58 I = 3 ;
59 strcpy(ch0, ch1);
60 while (I -- ) {
61 gets(ch1);
62 strcat(ch0, ch1);
63 }
64 stu1 = 0 ;
65 stu2 = 0 ;
66 // 生成两个初始状态
67 for (I = 0 , K = 16 ; I < 16 ; I ++ , K -- ) {
68 if (ch0[I] == ' b ' ) stu1 |= tsf[K];
69 if (ch0[I] == ' w ' ) stu2 |= tsf[K];
70 }
71 min1 = - 1 ;
72 Enum(stu1, min1);
73 min2 = - 1 ;
74 Enum(stu2, min2);
75 if (min1 == - 1 && min2 == - 1 ) puts( " Impossible " );
76 else if (min1 == - 1 ) printf( " %d\n " , min1);
77 else if (min2 == - 1 ) printf( " %d\n " , min2);
78 else printf( " %d\n " , min1 < min2 ? min1 : min2);
79 }
80 return 0 ;
81 }

 

你可能感兴趣的:(枚举)