方法同poj1753,但用在这题就TLE了,以下是TLE版本:

Code
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#define MAXSTATE 65536
5
#define MAXSIZE 16
6
#define ALLOPEN 0
7
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
else
35
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 |

Code
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#define MAXSTATE 65536
5
#define MAXSIZE 16
6
#define ALLOPEN 0
7
//循环队列结构体
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
}