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。感觉就是因为进制转化导致效率低下。。。
先把代码贴上,参考下大牛的代码再来做优化。
1
#include <stdio.h>2
#include <math.h>3
#include <malloc.h>4
#include <stdlib.h>5
#define MAXSIZE 166
int distance[0x10000];7

typedef struct node
{8
int data;9
struct node *next;10
}NODE;11

typedef struct
{12
NODE *front;13
NODE *rear;14
}QUEUE;15
QUEUE queue;16
void EnQueue(QUEUE *q, int d);17
int DnQueue(QUEUE *q);18
void 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
else29
q->front=q->rear=newNode;30
}31
int 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
//检查棋面是否一色46
int Win(int id)47


{48
if(id==0 || id==0xFFFF)49
return 1;50
return 0;51
}52
int 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
}167

int Empty(QUEUE *q)
{168
if(q->front==NULL)169
return 1;170
return 0;171
}172
void InitQueue(QUEUE *q)173


{174
q->front=q->rear=(NODE *)malloc(sizeof(NODE));175
q->front->next=NULL;176
}177
main(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 |
1
#include<stdio.h>2
#include <stdlib.h>3
#include <string.h>4
#define MAXSTATE 655365
#define MAXSIZE 166
#define ALL_BLACK 655357
#define ALL_WHITE 08
//定义队列结构体9

typedef struct node
{10
int data;11
struct node *next;12
}NODE;13

typedef struct
{14
NODE *front;15
NODE *rear;16
}QUEUE;17
//定义全局变量18
int state[MAXSTATE];19
QUEUE queue;20
void 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
else32
q->front=q->rear=newNode;33
}34
int 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
}48

int Empty(QUEUE *q)
{49
if(q->front==NULL)50
return 1;51
return 0;52
}53
int 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
}63
void 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 |
1
#include<stdio.h>2
#include <stdlib.h>3
#include <string.h>4
#define MAXSTATE 655365
#define MAXSIZE 166
#define ALL_BLACK 655357
#define ALL_WHITE 08
//循环队列结构体9

typedef struct
{10
int head, tail;11
int node[MAXSTATE];12
}QUEUE;13
//定义全局变量14
int distance[MAXSTATE];15
QUEUE queue;16
//队列操作函数17
void Init(QUEUE *q)18


{19
q->head=q->tail=0;20
}21
int Empty(QUEUE *q)22


{23
if ((q->head-q->tail)==0) return 1;24
return 0;25
}26
void 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
}35
int 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
}46
int 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
}56
void 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



浙公网安备 33010602011771号