poj1753 Flip Game
原题:http://acm.pku.edu.cn/JudgeOnline/problem?id=1753
第一个AC版本。效率极低:
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
4821173 | zen_chou | 1753 | Accepted | 552K | 782MS | C | 3385B | 2009-03-20 22:23:45 |
用的是BFS,枚举一共2^16种情况。
用1表示黑子,0表示白子的话每一种情况都可以生成一个id,比如id=1000 0000 0000 0000代表最左上角是黑子,其余15位都是白字的情况。然后将此id转化为十进制表示同样可以生成一个惟一的id。感觉就是因为进制转化导致效率低下。。。
先把代码贴上,参考下大牛的代码再来做优化。
Code
1#include <stdio.h>
2#include <math.h>
3#include <malloc.h>
4#include <stdlib.h>
5#define MAXSIZE 16
6int distance[0x10000];
7typedef struct node{
8 int data;
9 struct node *next;
10}NODE;
11typedef struct{
12 NODE *front;
13 NODE *rear;
14}QUEUE;
15QUEUE queue;
16void EnQueue(QUEUE *q, int d);
17int DnQueue(QUEUE *q);
18void EnQueue(QUEUE *q, int d)
19{
20 NODE *newNode;
21 newNode=(NODE *)malloc(sizeof(NODE));
22 newNode->data=d;
23 newNode->next=NULL;
24 if(q->front!=NULL){
25 q->rear->next=newNode;
26 q->rear=newNode;
27 }
28 else
29 q->front=q->rear=newNode;
30}
31int DeQueue(QUEUE *q)
32{
33 int temp;
34 NODE *oldNode;
35 if(q->front==NULL){
36 printf("List empty!\n");
37 return -1;
38 }
39 oldNode=q->front;
40 temp=q->front->data;
41 q->front=q->front->next;
42 free(oldNode);
43 return temp;
44}
45//检查棋面是否一色
46int Win(int id)
47{
48 if(id==0 || id==0xFFFF)
49 return 1;
50 return 0;
51}
52int Flip(int id, int pos)
53{
54 unsigned int a[MAXSIZE];
55 int i , ans=0;
56 for(i=MAXSIZE-1;i>=0;i--){
57 a[i]=id%2;
58 id/=2;
59 }
60 switch(pos){
61 case 0:
62 a[0]^=1;
63 a[1]^=1;
64 a[4]^=1;
65 break;
66 case 1:
67 a[0]^=1;
68 a[1]^=1;
69 a[2]^=1;
70 a[5]^=1;
71 break;
72 case 2:
73 a[1]^=1;
74 a[2]^=1;
75 a[3]^=1;
76 a[6]^=1;
77 break;
78 case 3:
79 a[2]^=1;
80 a[3]^=1;
81 a[7]^=1;
82 break;
83 case 4:
84 a[0]^=1;
85 a[4]^=1;
86 a[5]^=1;
87 a[8]^=1;
88 break;
89 case 5:
90 a[1]^=1;
91 a[4]^=1;
92 a[5]^=1;
93 a[6]^=1;
94 a[9]^=1;
95 break;
96 case 6:
97 a[2]^=1;
98 a[5]^=1;
99 a[6]^=1;
100 a[7]^=1;
101 a[10]^=1;
102 break;
103 case 7:
104 a[3]^=1;
105 a[6]^=1;
106 a[7]^=1;
107 a[11]^=1;
108 break;
109 case 8:
110 a[4]^=1;
111 a[8]^=1;
112 a[9]^=1;
113 a[12]^=1;
114 break;
115 case 9:
116 a[5]^=1;
117 a[8]^=1;
118 a[9]^=1;
119 a[10]^=1;
120 a[13]^=1;
121 break;
122 case 10:
123 a[6]^=1;
124 a[9]^=1;
125 a[10]^=1;
126 a[11]^=1;
127 a[14]^=1;
128 break;
129 case 11:
130 a[7]^=1;
131 a[10]^=1;
132 a[11]^=1;
133 a[15]^=1;
134 break;
135 case 12:
136 a[8]^=1;
137 a[12]^=1;
138 a[13]^=1;
139 break;
140 case 13:
141 a[9]^=1;
142 a[12]^=1;
143 a[13]^=1;
144 a[14]^=1;
145 break;
146 case 14:
147 a[10]^=1;
148 a[13]^=1;
149 a[14]^=1;
150 a[15]^=1;
151 break;
152 case 15:
153 a[11]^=1;
154 a[14]^=1;
155 a[15]^=1;
156 break;
157 default:
158 printf("Error!\n");
159 exit(0);
160 }
161
162 for(i=0;i<MAXSIZE;i++){
163 if (a[i]==1) ans+=(int)pow(2, MAXSIZE-i-1);
164 }
165 return ans;
166}
167int Empty(QUEUE *q){
168 if(q->front==NULL)
169 return 1;
170 return 0;
171}
172void InitQueue(QUEUE *q)
173{
174 q->front=q->rear=(NODE *)malloc(sizeof(NODE));
175 q->front->next=NULL;
176}
177main(int argc, char *argv[])
178{
179 char c[MAXSIZE];
180 int b[MAXSIZE];
181 QUEUE *q;
182 int i, id, id2;
183 //从文件中读取数据
184 //freopen("input.txt","r", stdin);
185 i=0;
186 while(scanf("%c%c%c%c\n", c+i, c+i+1, c+i+2, c+i+3)!=EOF) i+=4;
187 //将原始字符型数据先转换为二进制表示的整型,用以代表65536种状态中的唯一一种状态
188 for(i=0;i<MAXSIZE;i++){
189 if(c[i]=='b') b[i]=1;
190 else b[i]=0;
191 }
192 id=0;
193 for(i=0;i<MAXSIZE;i++){
194 if (b[i]==1) id+=b[i]*(int)pow(2, MAXSIZE-i-1);
195 }
196 //state[id]=1;
197
198 q=&queue;
199 for(i=0;i<0x10000;i++) distance[i]=-1;
200 //InitQueue(q);
201 EnQueue(q, id);
202 distance[id]=0;
203 if(Win(id)){
204 printf("0\n");
205 exit(0);
206 }
207
208 while(!Empty(q)){
209 id=DeQueue(q);
210 for(i=0;i<MAXSIZE;i++){
211 id2=Flip(id, i);
212 if(distance[id2]==-1){
213 distance[id2]=distance[id]+1;
214 if(Win(id2)){
215 printf("%d\n", distance[id2]);
216 exit(0);
217 }
218 EnQueue(q, id2);
219 }
220 }
221 }
222 printf("Impossible\n");
223}
1#include <stdio.h>
2#include <math.h>
3#include <malloc.h>
4#include <stdlib.h>
5#define MAXSIZE 16
6int distance[0x10000];
7typedef struct node{
8 int data;
9 struct node *next;
10}NODE;
11typedef struct{
12 NODE *front;
13 NODE *rear;
14}QUEUE;
15QUEUE queue;
16void EnQueue(QUEUE *q, int d);
17int DnQueue(QUEUE *q);
18void EnQueue(QUEUE *q, int d)
19{
20 NODE *newNode;
21 newNode=(NODE *)malloc(sizeof(NODE));
22 newNode->data=d;
23 newNode->next=NULL;
24 if(q->front!=NULL){
25 q->rear->next=newNode;
26 q->rear=newNode;
27 }
28 else
29 q->front=q->rear=newNode;
30}
31int DeQueue(QUEUE *q)
32{
33 int temp;
34 NODE *oldNode;
35 if(q->front==NULL){
36 printf("List empty!\n");
37 return -1;
38 }
39 oldNode=q->front;
40 temp=q->front->data;
41 q->front=q->front->next;
42 free(oldNode);
43 return temp;
44}
45//检查棋面是否一色
46int Win(int id)
47{
48 if(id==0 || id==0xFFFF)
49 return 1;
50 return 0;
51}
52int Flip(int id, int pos)
53{
54 unsigned int a[MAXSIZE];
55 int i , ans=0;
56 for(i=MAXSIZE-1;i>=0;i--){
57 a[i]=id%2;
58 id/=2;
59 }
60 switch(pos){
61 case 0:
62 a[0]^=1;
63 a[1]^=1;
64 a[4]^=1;
65 break;
66 case 1:
67 a[0]^=1;
68 a[1]^=1;
69 a[2]^=1;
70 a[5]^=1;
71 break;
72 case 2:
73 a[1]^=1;
74 a[2]^=1;
75 a[3]^=1;
76 a[6]^=1;
77 break;
78 case 3:
79 a[2]^=1;
80 a[3]^=1;
81 a[7]^=1;
82 break;
83 case 4:
84 a[0]^=1;
85 a[4]^=1;
86 a[5]^=1;
87 a[8]^=1;
88 break;
89 case 5:
90 a[1]^=1;
91 a[4]^=1;
92 a[5]^=1;
93 a[6]^=1;
94 a[9]^=1;
95 break;
96 case 6:
97 a[2]^=1;
98 a[5]^=1;
99 a[6]^=1;
100 a[7]^=1;
101 a[10]^=1;
102 break;
103 case 7:
104 a[3]^=1;
105 a[6]^=1;
106 a[7]^=1;
107 a[11]^=1;
108 break;
109 case 8:
110 a[4]^=1;
111 a[8]^=1;
112 a[9]^=1;
113 a[12]^=1;
114 break;
115 case 9:
116 a[5]^=1;
117 a[8]^=1;
118 a[9]^=1;
119 a[10]^=1;
120 a[13]^=1;
121 break;
122 case 10:
123 a[6]^=1;
124 a[9]^=1;
125 a[10]^=1;
126 a[11]^=1;
127 a[14]^=1;
128 break;
129 case 11:
130 a[7]^=1;
131 a[10]^=1;
132 a[11]^=1;
133 a[15]^=1;
134 break;
135 case 12:
136 a[8]^=1;
137 a[12]^=1;
138 a[13]^=1;
139 break;
140 case 13:
141 a[9]^=1;
142 a[12]^=1;
143 a[13]^=1;
144 a[14]^=1;
145 break;
146 case 14:
147 a[10]^=1;
148 a[13]^=1;
149 a[14]^=1;
150 a[15]^=1;
151 break;
152 case 15:
153 a[11]^=1;
154 a[14]^=1;
155 a[15]^=1;
156 break;
157 default:
158 printf("Error!\n");
159 exit(0);
160 }
161
162 for(i=0;i<MAXSIZE;i++){
163 if (a[i]==1) ans+=(int)pow(2, MAXSIZE-i-1);
164 }
165 return ans;
166}
167int Empty(QUEUE *q){
168 if(q->front==NULL)
169 return 1;
170 return 0;
171}
172void InitQueue(QUEUE *q)
173{
174 q->front=q->rear=(NODE *)malloc(sizeof(NODE));
175 q->front->next=NULL;
176}
177main(int argc, char *argv[])
178{
179 char c[MAXSIZE];
180 int b[MAXSIZE];
181 QUEUE *q;
182 int i, id, id2;
183 //从文件中读取数据
184 //freopen("input.txt","r", stdin);
185 i=0;
186 while(scanf("%c%c%c%c\n", c+i, c+i+1, c+i+2, c+i+3)!=EOF) i+=4;
187 //将原始字符型数据先转换为二进制表示的整型,用以代表65536种状态中的唯一一种状态
188 for(i=0;i<MAXSIZE;i++){
189 if(c[i]=='b') b[i]=1;
190 else b[i]=0;
191 }
192 id=0;
193 for(i=0;i<MAXSIZE;i++){
194 if (b[i]==1) id+=b[i]*(int)pow(2, MAXSIZE-i-1);
195 }
196 //state[id]=1;
197
198 q=&queue;
199 for(i=0;i<0x10000;i++) distance[i]=-1;
200 //InitQueue(q);
201 EnQueue(q, id);
202 distance[id]=0;
203 if(Win(id)){
204 printf("0\n");
205 exit(0);
206 }
207
208 while(!Empty(q)){
209 id=DeQueue(q);
210 for(i=0;i<MAXSIZE;i++){
211 id2=Flip(id, i);
212 if(distance[id2]==-1){
213 distance[id2]=distance[id]+1;
214 if(Win(id2)){
215 printf("%d\n", distance[id2]);
216 exit(0);
217 }
218 EnQueue(q, id2);
219 }
220 }
221 }
222 printf("Impossible\n");
223}
经过优化之后的第二个版本:任然是BFS,相比较第一个程序而言,删去了繁琐的二进制和十进制的转换,取而代之的是位运算。因此效率得到了很大的提高,但是相比较与POJ上的其他AC版本还不够。
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
4844178 | zen_chou | 1753 | Accepted | 512K | 157MS | C | 1976B | 2009-03-24 19:08:10 |
Code
1#include<stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#define MAXSTATE 65536
5#define MAXSIZE 16
6#define ALL_BLACK 65535
7#define ALL_WHITE 0
8//定义队列结构体
9typedef struct node{
10 int data;
11 struct node *next;
12}NODE;
13typedef struct{
14 NODE *front;
15 NODE *rear;
16}QUEUE;
17//定义全局变量
18int state[MAXSTATE];
19QUEUE queue;
20void EnQueue(QUEUE *q, int d)
21{
22 NODE *newNode;
23 newNode=(NODE *)malloc(sizeof(NODE));
24 newNode->data=d;
25 newNode->next=NULL;
26
27 if(q->front!=NULL){
28 q->rear->next=newNode;
29 q->rear=newNode;
30 }
31 else
32 q->front=q->rear=newNode;
33}
34int DeQueue(QUEUE *q)
35{
36 int temp;
37 NODE *oldNode;
38 if(q->front==NULL){
39 printf("List empty!\n");
40 return -1;
41 }
42 oldNode=q->front;
43 temp=q->front->data;
44 q->front=q->front->next;
45 free(oldNode);
46 return temp;
47}
48int Empty(QUEUE *q){
49 if(q->front==NULL)
50 return 1;
51 return 0;
52}
53int Flip(int id, int pos)
54{
55 int state;
56 state=id^1<<pos;//当前坐标翻转
57 if (pos>=4) state ^= (1<<(pos-4));//正上方位置翻转
58 if (pos%4!=0) state ^= (1<<(pos-1));
59 if (pos<=11) state ^= (1<<(pos+4));
60 if ((pos+1)%4!=0) state ^= (1<<(pos+1));
61 return state;
62}
63void main(int argc, char*argv[])
64{
65 int i=0, cur_state_id=0, new_state_id;
66 char c;
67 QUEUE *q;
68 q=&queue;
69 memset(state,-1, 65536*sizeof(int));
70 //freopen("input.txt", "r", stdin);
71 while(scanf("%c", &c)!=EOF){
72 if(c!='\n'){
73 if (c=='b') cur_state_id += 1<<i;
74 i++;
75 }
76 }
77 if(cur_state_id==ALL_BLACK || cur_state_id==ALL_WHITE){
78 printf("0\n");
79 return;
80 }
81 EnQueue(q, cur_state_id);
82 state[cur_state_id]=0;
83 while(!Empty(q)){
84 cur_state_id=DeQueue(q);
85
86 for(i=0;i<MAXSIZE;i++){
87 new_state_id=Flip(cur_state_id, i);
88 if(state[new_state_id]==-1){
89 if(new_state_id==ALL_BLACK || new_state_id==ALL_WHITE){
90 printf("%d\n", state[cur_state_id]+1);
91 return;
92 }
93 state[new_state_id]=state[cur_state_id]+1;
94 EnQueue(q, new_state_id);
95 }
96 }
97 }
98 printf("Impossible\n");
99 return;
100}
101
1#include<stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#define MAXSTATE 65536
5#define MAXSIZE 16
6#define ALL_BLACK 65535
7#define ALL_WHITE 0
8//定义队列结构体
9typedef struct node{
10 int data;
11 struct node *next;
12}NODE;
13typedef struct{
14 NODE *front;
15 NODE *rear;
16}QUEUE;
17//定义全局变量
18int state[MAXSTATE];
19QUEUE queue;
20void EnQueue(QUEUE *q, int d)
21{
22 NODE *newNode;
23 newNode=(NODE *)malloc(sizeof(NODE));
24 newNode->data=d;
25 newNode->next=NULL;
26
27 if(q->front!=NULL){
28 q->rear->next=newNode;
29 q->rear=newNode;
30 }
31 else
32 q->front=q->rear=newNode;
33}
34int DeQueue(QUEUE *q)
35{
36 int temp;
37 NODE *oldNode;
38 if(q->front==NULL){
39 printf("List empty!\n");
40 return -1;
41 }
42 oldNode=q->front;
43 temp=q->front->data;
44 q->front=q->front->next;
45 free(oldNode);
46 return temp;
47}
48int Empty(QUEUE *q){
49 if(q->front==NULL)
50 return 1;
51 return 0;
52}
53int Flip(int id, int pos)
54{
55 int state;
56 state=id^1<<pos;//当前坐标翻转
57 if (pos>=4) state ^= (1<<(pos-4));//正上方位置翻转
58 if (pos%4!=0) state ^= (1<<(pos-1));
59 if (pos<=11) state ^= (1<<(pos+4));
60 if ((pos+1)%4!=0) state ^= (1<<(pos+1));
61 return state;
62}
63void main(int argc, char*argv[])
64{
65 int i=0, cur_state_id=0, new_state_id;
66 char c;
67 QUEUE *q;
68 q=&queue;
69 memset(state,-1, 65536*sizeof(int));
70 //freopen("input.txt", "r", stdin);
71 while(scanf("%c", &c)!=EOF){
72 if(c!='\n'){
73 if (c=='b') cur_state_id += 1<<i;
74 i++;
75 }
76 }
77 if(cur_state_id==ALL_BLACK || cur_state_id==ALL_WHITE){
78 printf("0\n");
79 return;
80 }
81 EnQueue(q, cur_state_id);
82 state[cur_state_id]=0;
83 while(!Empty(q)){
84 cur_state_id=DeQueue(q);
85
86 for(i=0;i<MAXSIZE;i++){
87 new_state_id=Flip(cur_state_id, i);
88 if(state[new_state_id]==-1){
89 if(new_state_id==ALL_BLACK || new_state_id==ALL_WHITE){
90 printf("%d\n", state[cur_state_id]+1);
91 return;
92 }
93 state[new_state_id]=state[cur_state_id]+1;
94 EnQueue(q, new_state_id);
95 }
96 }
97 }
98 printf("Impossible\n");
99 return;
100}
101
继续改进,根据poj2965的经验,将链表队列用循环队列代替,效率大大提高!
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
4856678 | zen_chou | 1753 | Accepted | 472K | 32MS | C | 1886B | 2009-03-26 17:43:26 |
Code
1#include<stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#define MAXSTATE 65536
5#define MAXSIZE 16
6#define ALL_BLACK 65535
7#define ALL_WHITE 0
8//循环队列结构体
9typedef struct{
10 int head, tail;
11 int node[MAXSTATE];
12}QUEUE;
13//定义全局变量
14int distance[MAXSTATE];
15QUEUE queue;
16//队列操作函数
17void Init(QUEUE *q)
18{
19 q->head=q->tail=0;
20}
21int Empty(QUEUE *q)
22{
23 if ((q->head-q->tail)==0) return 1;
24 return 0;
25}
26void EnQueue(QUEUE *q ,int d)
27{
28 if ((q->tail+1)%MAXSTATE==q->head){
29 printf("Overflow!\n");
30 return;
31 }
32 q->node[q->tail]=d;
33 q->tail=(q->tail+1)%MAXSTATE;
34}
35int DeQueue(QUEUE *q)
36{
37 int d;
38 if (q->head==q->tail) {
39 printf("Underflow!\n");
40 return -1;
41 }
42 d=q->node[q->head];
43 q->head=(q->head+1)%MAXSTATE;
44 return d;
45}
46int Flip(int id, int pos)
47{
48 int state;
49 state=id^1<<pos;//当前坐标翻转
50 if (pos>=4) state ^= (1<<(pos-4));//正上方位置翻转
51 if (pos%4!=0) state ^= (1<<(pos-1));
52 if (pos<=11) state ^= (1<<(pos+4));
53 if ((pos+1)%4!=0) state ^= (1<<(pos+1));
54 return state;
55}
56void main(int argc, char*argv[])
57{
58 int i=0, cur_state_id=0, new_state_id;
59 char c;
60 QUEUE *q;
61 q=&queue;
62 memset(distance,-1, 65536*sizeof(int));
63 //freopen("input.txt", "r", stdin);
64 while(scanf("%c", &c)!=EOF){
65 if(c!='\n'){
66 cur_state_id<<=1;
67 if (c=='b') cur_state_id+=1;
68 }
69 }
70 if(cur_state_id==ALL_BLACK || cur_state_id==ALL_WHITE){
71 printf("0\n");
72 return;
73 }
74 EnQueue(q, cur_state_id);
75 distance[cur_state_id]=0;
76 while(!Empty(q)){
77 cur_state_id=DeQueue(q);
78
79 for(i=0;i<MAXSIZE;i++){
80 new_state_id=Flip(cur_state_id, i);
81 if(distance[new_state_id]==-1){
82 if(new_state_id==ALL_BLACK || new_state_id==ALL_WHITE){
83 printf("%d\n", distance[cur_state_id]+1);
84 return;
85 }
86 distance[new_state_id]=distance[cur_state_id]+1;
87 EnQueue(q, new_state_id);
88 }
89 }
90 }
91 printf("Impossible\n");
92 return;
93}
94
1#include<stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#define MAXSTATE 65536
5#define MAXSIZE 16
6#define ALL_BLACK 65535
7#define ALL_WHITE 0
8//循环队列结构体
9typedef struct{
10 int head, tail;
11 int node[MAXSTATE];
12}QUEUE;
13//定义全局变量
14int distance[MAXSTATE];
15QUEUE queue;
16//队列操作函数
17void Init(QUEUE *q)
18{
19 q->head=q->tail=0;
20}
21int Empty(QUEUE *q)
22{
23 if ((q->head-q->tail)==0) return 1;
24 return 0;
25}
26void EnQueue(QUEUE *q ,int d)
27{
28 if ((q->tail+1)%MAXSTATE==q->head){
29 printf("Overflow!\n");
30 return;
31 }
32 q->node[q->tail]=d;
33 q->tail=(q->tail+1)%MAXSTATE;
34}
35int DeQueue(QUEUE *q)
36{
37 int d;
38 if (q->head==q->tail) {
39 printf("Underflow!\n");
40 return -1;
41 }
42 d=q->node[q->head];
43 q->head=(q->head+1)%MAXSTATE;
44 return d;
45}
46int Flip(int id, int pos)
47{
48 int state;
49 state=id^1<<pos;//当前坐标翻转
50 if (pos>=4) state ^= (1<<(pos-4));//正上方位置翻转
51 if (pos%4!=0) state ^= (1<<(pos-1));
52 if (pos<=11) state ^= (1<<(pos+4));
53 if ((pos+1)%4!=0) state ^= (1<<(pos+1));
54 return state;
55}
56void main(int argc, char*argv[])
57{
58 int i=0, cur_state_id=0, new_state_id;
59 char c;
60 QUEUE *q;
61 q=&queue;
62 memset(distance,-1, 65536*sizeof(int));
63 //freopen("input.txt", "r", stdin);
64 while(scanf("%c", &c)!=EOF){
65 if(c!='\n'){
66 cur_state_id<<=1;
67 if (c=='b') cur_state_id+=1;
68 }
69 }
70 if(cur_state_id==ALL_BLACK || cur_state_id==ALL_WHITE){
71 printf("0\n");
72 return;
73 }
74 EnQueue(q, cur_state_id);
75 distance[cur_state_id]=0;
76 while(!Empty(q)){
77 cur_state_id=DeQueue(q);
78
79 for(i=0;i<MAXSIZE;i++){
80 new_state_id=Flip(cur_state_id, i);
81 if(distance[new_state_id]==-1){
82 if(new_state_id==ALL_BLACK || new_state_id==ALL_WHITE){
83 printf("%d\n", distance[cur_state_id]+1);
84 return;
85 }
86 distance[new_state_id]=distance[cur_state_id]+1;
87 EnQueue(q, new_state_id);
88 }
89 }
90 }
91 printf("Impossible\n");
92 return;
93}
94