天天看點

1024,我在調八數位問題程式...

最初知道 1024 是看到某論壇的文章的一堆跟帖都是 1024,并不知道是什麼意思。今天看到關于 1024 的文章,算是科普了:

原因就是因為 1024 M = 1GB,即一級棒的(片子)意思,老司機都懂的!
1024,我在調八數位問題程式...

對程式員來說,這麼重大的節日今天卻啥也沒做,就光調下面這個八數位問題的算法代碼,用雙向廣搜實作。

1024,自己調了一整天的程式很郁悶,這不應該是今天的正确打開方式。

最後,趁着這程式員節,祝願廣大 Coder 寫碼無 BUG, 心想事成!

貼上八數位題源碼(沒剪支掉無解的情況):

#include<stdio.h>
#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;
}
           
本文原創首發于微信公衆号 [ 林裡少年 ],歡迎關注第一時間擷取更新。
1024,我在調八數位問題程式...

繼續閱讀