uva 1343 非原创

uva1343

原作者

题目题意是:给你的棋盘,在A-H方向上可以拨动,问你最少拨动几次可以是中心图案的数字一致

解题思路:回溯法,剪枝

其中要把每次拨动的字母所代表的位置提前用数组表示;

然后在如果step+h()>maxd表示剪枝。

总之,用数组那里表示真的好棒,

自己太残了……!!!

#include <iostream>

#include <cstdio>

#include <cmath>

#include <cstring>

#include <algorithm>

#include <cstdlib>

#include <stack>

#include <cctype>

#include <string>

#include <malloc.h>

#include <queue>

#include <map>



using namespace std;



const int INF = 0xffffff;

const double esp = 10e-8;

const double Pi = 4 * atan(1.0);

const int Maxn = 100+10;

const long long mod =  2147483647;

const int dr[] = {1,0,-1,0,-1,1,-1,1};

const int dc[] = {0,1,0,-1,1,-1,-1,1};

typedef long long LL;



LL gac(LL a,LL b){

    return b?gac(b,a%b):a;

}

int shift[8][7] = {

    {0,2,6,11,15,20,22},

    {1,3,8,12,17,21,23},

    {10,9,8,7,6,5,4},

    {19,18,17,16,15,14,13},

    {23,21,17,12,8,3,1},

    {22,20,15,11,6,2,0},

    {13,14,15,16,17,18,19},

    {4,5,6,7,8,9,10}

};

int center[] = {6,7,8,11,12,15,16,17};

int re[] = {5,4,7,6,1,0,3,2};

int d[24];

char ans[1000];

int maxd;



bool is_good(){

    for(int i = 1;i < 8;i++){

        if(d[ center[0] ] != d[ center[i] ])

            return 0;

    }

    return 1;

}



void _move(int x){

    int tmp = d[ shift[x][0] ];

    for(int i = 0;i < 6;i++)

        d[ shift[x][i] ] = d[shift[x][i+1] ];

    d[shift[x][6]] = tmp;

}



int differ(int x){

    int cnt = 0;

    for(int i = 0;i < 8;i++){

        if(d[center[i]] != x){

            cnt++;

        }

    }

    return cnt;

}



int h(){

    return min(differ(1),min(differ(2),differ(3)));

}



bool dfs(int step){

    if(step == maxd){

        if(is_good()){

            ans[step] = '\0';

            return 1;

        }

        return 0;

    }

    if(step + h() > maxd)

        return 0;

    for(int i = 0;i < 8;i++){

        ans[step] = i + 'A';

        _move(i);

        if(dfs(step+1))

            return 1;

        _move(re[i]);

    }

    return 0;

}



int main()

{

#ifndef ONLINE_JUDGE

    freopen("inpt.txt","r",stdin);

#endif

    int goal[24];

    char str[] = "No moves needed";

    while(~scanf("%d",&goal[0]) && goal[0]){

        for(int i = 1;i < 24;i++){

            scanf("%d",&goal[i]);

        }

        for(maxd = 0;;maxd++){

            memcpy(d,goal,sizeof(d));

            if(dfs(0))

                break;

        }

        printf("%s\n%d\n",(maxd?ans:str),d[center[0]]);

    }

    return 0;

}

 

你可能感兴趣的:(uva)