zoukankan      html  css  js  c++  java
  • UVA-1343 The Rotation Game (IDA*)

    题目大意:数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。

    题目分析:IDA*,若当前在第cur层,中间八个数中1,2,3的个数分别为a,b,c。则d=8-max(a,b,c)便是达到目标还需要的理想次数,若cur+d>maxd,则剪枝。《入门经典》上提供了一种BFS的思路,分别以1,2,3为目标广搜3次,不过自己的码力还是太弱,并没有用那种方法AC。。。!!!

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    int a[24],d[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 g[8]={6,7,8,11,12,15,16,17};
    int ans;
    string ansp;
    
    bool dfs(int cur,int maxd,string path)
    {
        if(cur==maxd){
            int ok=1;
            for(int i=1;i<8;++i)
                if(a[g[i]]!=a[g[i-1]]){
                    ok=0;
                    break;
                }
            if(!ok)
                return false;
            ans=a[g[0]],ansp=path;
            return true;
        }
        int b[3]={0,0,0};
        for(int i=0;i<8;++i)
            ++b[a[g[i]]-1];
        int dd=8-max(max(b[0],b[1]),b[2]);
        if(cur+dd>maxd)
            return false;
        for(int i=0;i<8;++i){
            int v=a[d[i][0]];
            for(int j=0;j<6;++j)
                a[d[i][j]]=a[d[i][j+1]];
            a[d[i][6]]=v;
            if(dfs(cur+1,maxd,path+char(i+'A')))
                return true;
            v=a[d[i][6]];
            for(int j=6;j>0;--j)
                a[d[i][j]]=a[d[i][j-1]];
            a[d[i][0]]=v;
        }
        return false;
    }
    
    int main()
    {
        while(scanf("%d",&a[0])&&a[0])
        {
            for(int i=1;i<24;++i)
                scanf("%d",a+i);
    
            ans=-1;
            for(int maxd=0;;++maxd){
                if(dfs(0,maxd,"")){
                    if(maxd==0)
                        printf("No moves needed
    ");
                    else
                        cout<<ansp<<endl;
                    printf("%d
    ",ans);
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    反射,插件示例
    几种常见语言的基本语法对比:回调 事件 -java
    几种常见语言的基本语法对比:事件 ,回调-c#
    几种常见语言的基本语法对比:类,继承,多态。
    几种常见语言的基本语法对比:集合
    几种常见语言的基本语法对比:字符串
    几种常见语言的基本语法对比:数字处理
    几种常见语言的基本语法对比
    java 学习 语言特色。
    Java中“==和equals”的区别
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4833993.html
Copyright © 2011-2022 走看看