UVA 1343 The Rotation Game

https://vjudge.net/problem/UVA-1343

 

题意:‘#’行棋盘上有8个1,8个2,8个3,可以往8个方向旋转

问中间8个格数字相同的最少旋转次数

输出字典序最小的方案数,并输出中间是哪个数

 

 

#include<cstdio>
#include<algorithm>

using namespace std;

int mov[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 pos[8]={6,7,8,11,12,15,16,17}; 
int rev[8]={5,4,7,6,1,0,3,2}; 

int a[24];
int maxd;
char order[10001];

int judge(int x)
{
    int sum=0;
    for(int i=0;i<8;i++)
        if(a[pos[i]]!=x) sum++;
    return sum;
}

int h()
{
    return min(judge(1),min(judge(2),judge(3)));
}

void move(int i)
{
    int t=a[mov[i][0]];
    for(int j=0;j<6;j++) a[mov[i][j]]=a[mov[i][j+1]];
    a[mov[i][6]]=t;
}

bool dfs(int d)
{
    if(!judge(a[pos[0]]))
    {
        order[d]='\0';
        puts(order);
        return true;
    }
    if(d+h()>maxd) return false;
    for(int i=0;i<8;i++)
    {
        move(i);
        order[d]=char(i+'A');
        if(dfs(d+1)) return true;
        move(rev[i]);
    }
    return false;
} 

int main()
{
    while(1)
    {
        scanf("%d",&a[0]);
        if(!a[0]) return 0;
        for(int i=1;i<24;i++) scanf("%d",&a[i]);
        if(!judge(a[pos[0]]))  puts("No moves needed");
        else for(maxd=1;;maxd++) if(dfs(0)) break;
        printf("%d\n",a[6]);
    }
}

 

posted @ 2017-10-14 18:57  TRTTG  阅读(241)  评论(0编辑  收藏  举报