方法同poj1753,但用在这题就TLE了,以下是TLE版本:
1
#include <stdio.h>2
#include <stdlib.h>3
#include <string.h>4
#define MAXSTATE 655365
#define MAXSIZE 166
#define ALLOPEN 07

8
//队列结构体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
QUEUE queue;19
int distance[MAXSTATE];20
int position[MAXSTATE];21
int parentState[MAXSTATE];22
//入队列函数23
void EnQueue(QUEUE *q, int d)24


{25
NODE *newNode;26
newNode=(NODE *)malloc(sizeof(NODE));27
newNode->data=d;28
newNode->next=NULL;29
30

if(q->front!=NULL)
{31
q->rear->next=newNode;32
q->rear=newNode;33
}34
else35
q->front=q->rear=newNode;36
}37
//出队列函数38
int DeQueue(QUEUE *q)39


{40
int temp;41
NODE *oldNode;42

if(q->front==NULL)
{43
printf("List empty!\n");44
return -1;45
}46
oldNode=q->front;47
temp=q->front->data;48
q->front=q->front->next;49
free(oldNode);50
return temp;51
}52
//判断队列是否为空53

int Empty(QUEUE *q)
{54
if(q->front==NULL)55
return 1;56
return 0;57
}58

59
int ChangeState(int id, int pos)60


{61
int t, new_id;62
new_id=id^1<<pos;63

if (pos>=4)
{64
t=pos-4;65

while(t>=0)
{66
new_id^=1<<t;67
t-=4;68
}69
}70

if(pos<=11)
{71
t=pos+4;72

while(t<=15)
{73
new_id^=1<<t;74
t+=4;75
}76
}77

if(pos%4>0)
{//向左78
t=pos-1;79

while(t%4!=3 && t>=0)
{80
new_id^=1<<t;81
--t;82
}83
}84

if(pos%4<3)
{//向右85
t=pos+1;86

while(t%4!=0)
{87
new_id^=1<<t;88
++t;89
}90
}91
return new_id;92
}93

94
void Output(int stat)95


{96
int cur_state, len=0, i;97
int arr_x[MAXSIZE];98
int arr_y[MAXSIZE];99
100
cur_state=stat;101
printf("%d\n", distance[cur_state]);102

while(distance[cur_state]!=0)
{103
arr_x[len]=position[cur_state]/4+1;104
arr_y[len++]=position[cur_state]%4+1;105
cur_state=parentState[cur_state];106
}107

for (i=len-1;i>=0;i--)
{108
printf("%d %d\n", arr_x[i], arr_y[i]);109
}110
}111

112
void main(int argc, char *argv[])113


{114
char c;115
int cur_state=0, new_state;116
int i=0;117
QUEUE *q;118
q=&queue;119
//freopen("input.txt", "r", stdin);120
121

while(scanf("%c", &c)!=EOF)
{122

if(c!='\n')
{123
if (c=='+') cur_state += 1<<i;124
i++;125
}126
}127
memset(distance, -1, MAXSTATE*sizeof(int));128
129

if(cur_state==ALLOPEN)
{130
printf("0\n");131
return;132
}133
parentState[cur_state]=-1;134
distance[cur_state]=0;135
position[cur_state]=-1;136
EnQueue(q, cur_state);137

while(!Empty(q))
{138
cur_state=DeQueue(q);139

for (i=0;i<MAXSIZE;i++)
{140
new_state=ChangeState(cur_state, i);141

if (new_state==ALLOPEN)
{//成功142
parentState[new_state]=cur_state;143
position[new_state]=i;144
distance[new_state]=distance[cur_state]+1;145
Output(new_state);146
return;147
}148

if (distance[new_state]==-1)
{//未访问过结点149
distance[new_state]=distance[cur_state]+1;150
position[new_state]=i;151
parentState[new_state]=cur_state;152
EnQueue(q, new_state);153
}154
}155
}156
}优化过程:将需要改变的状态存放在一个一维数组当中,这样就减少了每次改变状态时的开销。如下所示:
int state[MAXSIZE]={
0xF888,0xF444,0xF222,0xF111,
0x8F88,0x4F44,0x2F22,0x1F11,
0x88F8,0x44F4,0x22F2,0x11F1,
0x888F,0x444F,0x222F,0x111F};
0xF888转换为二进制是1111 1000 1000 1000,换一种格式:
1111
1000
1000
1000
表示改变坐标(0,0)的状态时第一列和第一行的状态都要改变,这样只要和当前状态XOR一下就可以得到新的状态了。
再次提交了一次任然是TLE。。。看来效果不是很明显。
继续改进,发现队列用的是链表实现,效率没有用数组高,因而将链表用数组全部重写。
再次提交,果然AC了。
| Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
| 4856540 | zen_chou | 2965 | Accepted | 1220K | 219MS | C | 2387B | 2009-03-26 17:27:36 |
1
#include <stdio.h>2
#include <stdlib.h>3
#include <string.h>4
#define MAXSTATE 655365
#define MAXSIZE 166
#define ALLOPEN 07
//循环队列结构体8

typedef struct
{9
int head, tail;10
int node[MAXSTATE];11
}QUEUE;12
//队列函数13
void Init(QUEUE *q)14


{15
q->head=q->tail=0;16
}17
int Empty(QUEUE *q)18


{19
if ((q->head-q->tail)==0) return 1;20
return 0;21
}22
void EnQueue(QUEUE *q ,int d)23


{24

if ((q->tail+1)%MAXSTATE==q->head)
{25
printf("Overflow!\n");26
return;27
}28
q->node[q->tail]=d;29
q->tail=(q->tail+1)%MAXSTATE;30
}31
int DeQueue(QUEUE *q)32


{33
int d;34

if (q->head==q->tail)
{35
printf("Underflow!\n");36
return -1;37
}38
d=q->node[q->head];39
q->head=(q->head+1)%MAXSTATE;40
return d;41
}42
//全局变量43
int distance[MAXSTATE];44
int position[MAXSTATE];45
int parentState[MAXSTATE];46
QUEUE queue;47

int state[MAXSIZE]=
{48
0xF888,0xF444,0xF222,0xF111,49
0x8F88,0x4F44,0x2F22,0x1F11,50
0x88F8,0x44F4,0x22F2,0x11F1,51
0x888F,0x444F,0x222F,0x111F};52

53

54
int ChangeState(int id, int pos)55


{56
int new_id;57
new_id=id^state[pos];58
return new_id;59
}60

61
void Output(int stat)62


{63
int cur_state, len=0, i;64
int arr_x[MAXSIZE];65
int arr_y[MAXSIZE];66
cur_state=stat;67
printf("%d\n", distance[cur_state]);68

while(distance[cur_state]!=0)
{69
arr_x[len]=position[cur_state]/4+1;70
arr_y[len++]=position[cur_state]%4+1;71
cur_state=parentState[cur_state];72
}73

for (i=len-1;i>=0;i--)
{74
printf("%d %d\n", arr_x[i], arr_y[i]);75
}76
}77

78
void main(int argc, char *argv[])79


{80
char c;81
int cur_state=0, new_state;82
int i=0;83
QUEUE *q;84
q=&queue;85
//freopen("input.txt", "r", stdin);86
87

while(scanf("%c", &c)!=EOF)
{88

if(c!='\n')
{89
cur_state<<=1;90
if (c=='+') cur_state+=1;91
}92
}93
memset(distance, -1, MAXSTATE*sizeof(int));94
95

if(cur_state==ALLOPEN)
{96
printf("0\n");97
return;98
}99
parentState[cur_state]=-1;100
distance[cur_state]=0;101
position[cur_state]=-1;102
EnQueue(q, cur_state);103

while(!Empty(q))
{104
cur_state=DeQueue(q);105

for (i=0;i<MAXSIZE;i++)
{106
new_state=ChangeState(cur_state, i);107

if (new_state==ALLOPEN)
{//成功108
parentState[new_state]=cur_state;109
position[new_state]=i;110
distance[new_state]=distance[cur_state]+1;111
Output(new_state);112
return;113
}114

if (distance[new_state]==-1)
{//未访问过结点115
distance[new_state]=distance[cur_state]+1;116
position[new_state]=i;117
parentState[new_state]=cur_state;118
EnQueue(q, new_state);119
}120
}121
}122
}











