您的位置:首页 > 其它

poj1753 Flip Game

2009-03-20 22:26 309 查看
原题:http://acm.pku.edu.cn/JudgeOnline/problem?id=1753

第一个AC版本。效率极低:

Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time
4821173zen_chou1753Accepted552K782MSC3385B2009-03-20 22:23:45
用的是BFS,枚举一共2^16种情况。

用1表示黑子,0表示白子的话每一种情况都可以生成一个id,比如id=1000 0000 0000 0000代表最左上角是黑子,其余15位都是白字的情况。然后将此id转化为十进制表示同样可以生成一个惟一的id。感觉就是因为进制转化导致效率低下。。。

先把代码贴上,参考下大牛的代码再来做优化。

#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
#define MAXSIZE 16
int distance[0x10000];
typedef struct node{
int data;
struct node *next;
}NODE;
typedef struct{
NODE *front;
NODE *rear;
}QUEUE;
QUEUE queue;
void EnQueue(QUEUE *q, int d);
int DnQueue(QUEUE *q);
void EnQueue(QUEUE *q, int d)
{
NODE *newNode;
newNode=(NODE *)malloc(sizeof(NODE));
newNode->data=d;
newNode->next=NULL;
if(q->front!=NULL){
q->rear->next=newNode;
q->rear=newNode;
}
else
q->front=q->rear=newNode;
}
int DeQueue(QUEUE *q)
{
int temp;
NODE *oldNode;
if(q->front==NULL){
printf("List empty!/n");
return -1;
}
oldNode=q->front;
temp=q->front->data;
q->front=q->front->next;
free(oldNode);
return temp;
}
//检查棋面是否一色
int Win(int id)
{
if(id==0 || id==0xFFFF)
return 1;
return 0;
}
int Flip(int id, int pos)
{
unsigned int a[MAXSIZE];
int i , ans=0;
for(i=MAXSIZE-1;i>=0;i--){
a[i]=id%2;
id/=2;
}
switch(pos){
case 0:
a[0]^=1;
a[1]^=1;
a[4]^=1;
break;
case 1:
a[0]^=1;
a[1]^=1;
a[2]^=1;
a[5]^=1;
break;
case 2:
a[1]^=1;
a[2]^=1;
a[3]^=1;
a[6]^=1;
break;
case 3:
a[2]^=1;
a[3]^=1;
a[7]^=1;
break;
case 4:
a[0]^=1;
a[4]^=1;
a[5]^=1;
a[8]^=1;
break;
case 5:
a[1]^=1;
a[4]^=1;
a[5]^=1;
a[6]^=1;
a[9]^=1;
break;
case 6:
a[2]^=1;
a[5]^=1;
a[6]^=1;
a[7]^=1;
a[10]^=1;
break;
case 7:
a[3]^=1;
a[6]^=1;
a[7]^=1;
a[11]^=1;
break;
case 8:
a[4]^=1;
a[8]^=1;
a[9]^=1;
a[12]^=1;
break;
case 9:
a[5]^=1;
a[8]^=1;
a[9]^=1;
a[10]^=1;
a[13]^=1;
break;
case 10:
a[6]^=1;
a[9]^=1;
a[10]^=1;
a[11]^=1;
a[14]^=1;
break;
case 11:
a[7]^=1;
a[10]^=1;
a[11]^=1;
a[15]^=1;
break;
case 12:
a[8]^=1;
a[12]^=1;
a[13]^=1;
break;
case 13:
a[9]^=1;
a[12]^=1;
a[13]^=1;
a[14]^=1;
break;
case 14:
a[10]^=1;
a[13]^=1;
a[14]^=1;
a[15]^=1;
break;
case 15:
a[11]^=1;
a[14]^=1;
a[15]^=1;
break;
default:
printf("Error!/n");
exit(0);
}

for(i=0;i<MAXSIZE;i++){
if (a[i]==1) ans+=(int)pow(2, MAXSIZE-i-1);
}
return ans;
}
int Empty(QUEUE *q){
if(q->front==NULL)
return 1;
return 0;
}
void InitQueue(QUEUE *q)
{
q->front=q->rear=(NODE *)malloc(sizeof(NODE));
q->front->next=NULL;
}
main(int argc, char *argv[])
{
char c[MAXSIZE];
int b[MAXSIZE];
QUEUE *q;
int i, id, id2;
//从文件中读取数据
//freopen("input.txt","r", stdin);
i=0;
while(scanf("%c%c%c%c/n", c+i, c+i+1, c+i+2, c+i+3)!=EOF) i+=4;
//将原始字符型数据先转换为二进制表示的整型,用以代表65536种状态中的唯一一种状态
for(i=0;i<MAXSIZE;i++){
if(c[i]=='b') b[i]=1;
else b[i]=0;
}
id=0;
for(i=0;i<MAXSIZE;i++){
if (b[i]==1) id+=b[i]*(int)pow(2, MAXSIZE-i-1);
}
//state[id]=1;

q=&queue;
for(i=0;i<0x10000;i++) distance[i]=-1;
//InitQueue(q);
EnQueue(q, id);
distance[id]=0;
if(Win(id)){
printf("0/n");
exit(0);
}

while(!Empty(q)){
id=DeQueue(q);
for(i=0;i<MAXSIZE;i++){
id2=Flip(id, i);
if(distance[id2]==-1){
distance[id2]=distance[id]+1;
if(Win(id2)){
printf("%d/n", distance[id2]);
exit(0);
}
EnQueue(q, id2);
}
}
}
printf("Impossible/n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: