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;
}

 

posted @ 2015-02-17 15:40  寒饼干  阅读(255)  评论(0编辑  收藏  举报