1. 程式人生 > >網易遊戲研發工程師筆試題

網易遊戲研發工程師筆試題

題目描述

Q最近被邀請去參加了網易最牛大腦的節目,挑戰數字魔方的專案。

數字魔方為一個3x3的矩陣,矩陣中的每個數字都是(1…9)中的數字,且數字魔方中的數字可能重複。每4個相鄰的數字我們稱為1個子魔方,整個數字魔方共有4個子魔方(如下圖所示)。每一次操作可以選擇對某個子魔方順時針旋轉90度,180度或者270度。每個子魔方可以進行多次操作。

 

對子魔方1進行一次操作,順時針旋轉90度,180度,270度後的狀態:


專案的挑戰任務是,給定數字魔方的一個初始狀態,以及一個目標狀態,問最少操作多少次可以使得魔方從初始狀態改變為目標狀態。

Q求助於你,希望你能告訴他完成任務的最少操作次數是多少,或者任務不可能完成。

輸入描述

:

輸入的第一行為一個正整數TT<=20),表示測試資料組數。接下來有T組資料。每組資料有6行。其中前3行為數字魔方的初始狀態,後3行為目標狀態。每個資料之後有一個空行。保證魔方中的數字為(1…9)中的數字。

輸出描述:

對於每一組資料,輸出一行,包含一個整數,為最少操作次數。如果不能完成目標,則輸出-1

示例1

輸入

2

1 2 3

4 5 6

7 8 9

5 4 1

6 2 3

7 8 9

1 2 3

4 5 6

7 8 9

2 5 3

1 4 6

7 8 9

輸出

3

1

說明

第一個樣例為對子魔方1旋轉90度,然後對子魔方2旋轉90度,再對子魔方1旋轉90度。第二個樣例為對子魔方1旋轉270度。

 1.思路:

將魔方狀態轉換成一組字串,由於字串長度為9,其可能出現的狀態的總數一定(不會超過9的階乘),因此採用BFS廣度優先搜尋,並使用雜湊表來儲存狀態(若使用陣列來儲存狀態,則需要自己實現“改進的康拓展開式”);res初始化為-1,若得到答案,則break並返回res,若得不到答案,則返回-1.

2.程式碼:

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <cstring>
#include <unordered_map>
using namespace std;
int movx[4]={0,1,3,4};
int fac[9]={1,1,2,6,24,120,720,5040,40320};
bool vis[362890];
//陣列索引直接查詢,時間複雜度O(1),但需要用康拓展開,自己實現對映過程
//雜湊表由紅黑樹實現,其查詢時間複雜度為O(logN)
//C++find函式查詢,時間複雜度為O(N);

struct node
{
    string str;
    int step;
};

int str2int(string str)
{
    int cnt[9]={0};
    int res=0;
    int i,j;
    for(i=0;i<9;i++)
        cnt[str[i]-'1']++;
    for(i=0;i<9;i++)
    {
        int x=str[i]-'1';
        int y=0;
        for(j=0;j<x;j++)
            y+=cnt[j];
        res+=y*fac[8-i];
        cnt[x]--;
    }
    return res;
}
string rorate_str_90(string str,int x)
{
    char ch;
    int dx=movx[x];
    ch=str[dx];
    str[dx]=str[dx+3];
    str[dx+3]=str[dx+4];
    str[dx+4]=str[dx+1];
    str[dx+1]=ch;
    return str;
}
string rorate_str_180(string str,int x)
{
    char ch;
    int dx=movx[x];
    ch=str[dx];
    str[dx]=str[dx+4];
    str[dx+4]=ch;
    ch=str[dx+1];
    str[dx+1]=str[dx+3];
    str[dx+3]=ch;
    return str;
}
string rorate_str_270(string str,int x)
{
    char ch;
    int dx=movx[x];
    ch=str[dx];
    str[dx]=str[dx+1];
    str[dx+1]=str[dx+4];
    str[dx+4]=str[dx+3];
    str[dx+3]=ch;
    return str;
}
string calc_str(const vector<int> num)
{
    string str="";
    for(int i=0;i<9;i++)
        str+=('0'+num[i]);
    return str;
}
int main()
{
    int t,i,tmp;
    cin>>t;
    while(t--)
    {
        vector<int> init;
        vector<int> res;
        string init_str,res_str;
        int minx=-1;
        unordered_map<string, int> vis2; //初始化雜湊表
//        memset(vis,0,sizeof(vis));
        queue<node> q;
        int num;
        for(i=0;i<9;i++)
        {
            cin>>tmp;
            init.push_back(tmp);
        }
        for(i=0;i<9;i++)
        {
            cin>>tmp;
            res.push_back(tmp);
        }
        init_str=calc_str(init);
        res_str=calc_str(res);
        node init_node;
        init_node.step=0;
        init_node.str=init_str;
        q.push(init_node);
//        vis[str2int(init_node.str)]=true;
        while(!q.empty())
        {
            node tn,nx;
            tn=q.front();q.pop();
            if(tn.str==res_str)
            {
                minx=tn.step;
                break;
            }
            for(i=0;i<4;i++)
            {
                nx.str=rorate_str_90(tn.str,i);
                if(vis2.find(nx.str) == vis2.end()) {
                    vis2[nx.str] = 1;
                    nx.step = tn.step+1;
                    q.push(nx);
                }
//                num=str2int(nx.str);
//                if(!vis[num])
//                {
//                    vis[num]=1;
//                    nx.step=tn.step+1;
//                    q.push(nx);
//                }
                nx.str=rorate_str_180(tn.str,i);
                if(vis2.find(nx.str) == vis2.end()) {
                    vis2[nx.str] = 1;
                    nx.step = tn.step+1;
                    q.push(nx);
                }
//                num=str2int(nx.str);
//                if(!vis[num])
//                {
//                    vis[num]=1;
//                    nx.step=tn.step+1;
//                    q.push(nx);
//                }
                nx.str=rorate_str_270(tn.str,i);
                if(vis2.find(nx.str) == vis2.end()) {
                    vis2[nx.str] = 1;
                    nx.step = tn.step+1;
                    q.push(nx);
                }
//                num=str2int(nx.str);
//                if(!vis[num])
//                {
//                    vis[num]=1;
//                    nx.step=tn.step+1;
//                    q.push(nx);
//                }
            }

        }
        cout<<minx<<endl;
    }
    return 0;
}


 3.執行結果: