最初知道 1024 是看到某论坛的帖子的一堆跟帖都是 1024,并不知道是什么意思。今天看到关于 1024 的文章,算是科普了:
原因就是因为 1024 M = 1GB,即一级棒的(片子)意思,老司机都懂的!
对程序员来说,这么重大的节日今天却啥也没做,就光调下面这个八数码问题的算法代码,用双向广搜实现。
1024,自己调了一整天的程序很郁闷,这不应该是今天的正确打开方式。
最后,趁着这程序员节,祝愿广大 Coder 写码无 BUG, 心想事成!
贴上八数码题源码(没剪支掉无解的情况):
#include
#define rint register int
#define UL unsigned long
#define SIZE (5)
#define MAX (362889)
#define BORDER (-1)
#define VIS_1 (1)
#define VIS_2 (2)
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {1, -1, 0, 0};
const int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
typedef struct Node_
{
int x;
int y;
int step;
UL state;
}Node;
int vis[MAX] = {0};
int map[SIZE][SIZE];
Node Q[5000];
int A[9];
void init();
UL cantor(int a[], int len);
void cantorReverse(int a[], int len, int k);
int* convertFromMapToArray(int m[5][5]);
void convertFromArrayToMap(int m[5][5]);
UL getState(int a[9]);
void BFS();
//康拓展开函数
UL cantor(int a[], int len)
{
UL sum = 0;
for(rint i = 0; i < len; i++) //a数组是给出的数,n是元素个数
{
UL cnt = 0; //统计有多少数比a[i]小
for(rint j = i+1; j < len; j++)
{
if(a[i] > a[j])
cnt++;
}
sum+=cnt*fac[len-i-1];
}
return sum;
}
void cantorReverse(int a[], int len, int k)
{
int temp;
int vis[20] = {0};
for(rint i = 0; i < len; i++)
{
temp = k/fac[len - 1 - i];
k %= fac[len - 1 - i];
for(rint j = 0; j <= temp; j++)
{
if(vis[j]) //如果有比他小的数已经用过了
temp++;
}
a[i] = temp;
vis[temp] = 1;
}
}
int* convertFromMapToArray(int m[5][5])
{
int cnt = 0;
for(rint i = 1; i <= 3; i++)
{
for(rint j = 1; j <= 3; j++)
{
A[cnt++] = m[i][j];
}
}
return A;
}
void convertFromArrayToMap(int m[5][5])
{
int cnt = 0;
for(rint i = 1; i <= 3; i++)
{
for(rint j = 1; j <= 3; j++)
{
m[i][j] = A[cnt++];
}
}
}
UL getState(int a[9])
{
return cantor(a, 9);
}
void init()
{
int X,Y;
//init the queue
for(rint i = 0; i < 5000; i++)
{
Q[i].step = 0;
Q[i].state = 0;
Q[i].x = 0;
Q[i].y = 0;
}
//init the vis
for(rint i = 0; i < MAX; i++)
vis[i] = 0;
//add border for map
for(rint i = 0; i < SIZE; i++)
{
map[i][0] = map[i][SIZE - 1] = -1;
map[0][i] = map[SIZE - 1][i] = -1;
}
//input start state data
for(rint i = 1; i <= 3; i++)
{
for(rint j = 1; j <= 3; j++)
{
scanf("%d", &map[i][j]);
if(map[i][j] == 0)
{
X = i;
Y = j;
}
}
}
Q[0].x = X;
Q[0].y = Y;
Q[0].state = getState(convertFromMapToArray(map)); //start state
vis[Q[0].state] = VIS_1;
//input end state data
for(rint i = 1; i <= 3; i++)
{
for(rint j = 1; j <= 3; j++)
{
scanf("%d", &map[i][j]);
if(map[i][j] == 0)
{
X = i;
Y = j;
}
}
}
Q[1].x = X;
Q[1].y = Y;
Q[1].state = getState(convertFromMapToArray(map)); //start state
vis[Q[1].state] = VIS_2;
}
void BFS()
{
int front, rear;
front = 0;
rear = 2;
bool found = false;
UL curState, nextState;
Node curNode;
while(front < rear && !found)
{
curNode = Q[front++];
int x = curNode.x;
int y = curNode.y;
int step = curNode.step;
curState = curNode.state;
cantorReverse(A, 9, curState);
convertFromArrayToMap(map);
int temp = map[x][y];
for(rint i = 0; i < 4; i++)
{
int x1 = x + dx[i];
int y1 = y + dy[i];
if(map[x1][y1] != BORDER)
{
map[x][y] = map[x1][y1];
map[x1][y1] = temp;
nextState = getState(convertFromMapToArray(map));
if(!vis[nextState])
{
Q[rear].x = x1;
Q[rear].y = y1;
Q[rear].state = nextState;
Q[rear].step = step + 1;
vis[nextState] = vis[curState];
rear++;
}
else if(vis[curState] != vis[nextState])
{
found = true;
break;
}
map[x1][y1] = map[x][y];
map[x][y] = temp;
}
}
}
Node nextNode;
for(rint i = 1; i < rear; i++)
{
if(nextState == Q[i].state)
{
nextNode = Q[i];
break;
}
}
printf("%d\n", nextNode.step + curNode.step + 1);
}
int main()
{
freopen("1231.txt", "r", stdin);
setbuf(stdout, NULL);
int T;
scanf("%d", &T);
for(rint t = 1; t <= T; t++)
{
init();
printf("#%d ", t);
BFS();
}
return 0;
}
本文原创首发于微信公众号 [ 林里少年 ],欢迎关注第一时间获取更新。