• 100722A


    这道题抄了答案:

    思路:旋转,其实只用旋转四次,因为在换行的过程中旋转其实是没有意义的,因为行列只不过转了个角度。然后主要的是行列的交换,这里我很头疼,写了个盲目搜索,当然wa掉了

    问了问某位同志,是这样做的,很巧妙:其实这是一个全排列,一个三个数的全排列套了三个数的全排列,然后该怎么做呢?这里运用了一个巧妙的方法:range

    range很巧妙,分两种情况:当我选完了三列时,这时我需要新的一列,那么我返回(0,8),意思是下一个列可以从(0,8)之间没用过的任选。第二呢,是我正在选三列中的一列,这时

    我看看上一列我选的什么,这次我选的只能是(上一列设为x)[x/3*3,x/3*3+2]举个例子:(0,1,2) (3,4,5)(6,7,8)其实就是这三个块,他们每三个数必须绑在一起

    然后我搜完了列之后搜行(搜行的时候我犯了个错误,对应残缺的数独下标没想清楚,debug了很长时间,下次应该想清楚)然后就是重复同样的过程,只不过要加上置换,

    置换需要用一个额外的数组记录是那一列的时候替换的,因为会导致还原的时候不知道哪些要还原,然后就好了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    typedef pair<int,int> pii;
    
    string s;
    int used_col[10],used_row[10],place[10];
    int pos_row[10],pos_col[10],place_flag[10];
    int b[10][10],c[10][10];
    
    void init()
    {
        memset(place_flag,-1,sizeof(place_flag));
        memset(place,-1,sizeof(place));
        memset(pos_row,-1,sizeof(pos_row));
        memset(pos_col,-1,sizeof(pos_col));
        memset(used_row,0,sizeof(used_row));
        memset(used_col,0,sizeof(used_col));    
    }
    
    pii get_range(int pos,int f)
    {
        if(pos%3==0) return pii(0,8);
        int head=0;
        if(!f) head=pos_row[pos-1]/3*3;
        else head=pos_col[pos-1]/3*3;
        return pii(head,head+2);
    }
    
    void rotate()
    {
        int a[10][10];memset(a,0,sizeof(a));
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++) a[9-j-1][i]=b[i][j];
        for(int i=0;i<9;i++) 
            for(int j=0;j<9;j++) b[i][j]=a[i][j];    
    }
    
    bool go_col(int d)
    {
        if(d==9) return true;
        pii range=get_range(d,1);
        for(int i=range.first;i<=range.second;i++) if(!used_col[i])
        {
            used_col[i]=1;
            pos_col[d]=i;
            bool flag=false;
            for(int j=0;j<9;j++)
            {
                int x=b[pos_row[j]][pos_col[d]],y=c[j][d];
                if(y==0) continue;
                if(place[x]!=-1&&place[x]!=y) {flag=true;break;}
                if(place[x]==-1)
                { 
                    place[x]=y;
                    place_flag[x]=d;
                }
            }
            if(!flag) if(go_col(d+1)) return true;    
            for(int j=0;j<9;j++) 
            {
                int x=b[pos_row[j]][pos_col[d]];
                if(place_flag[x]==d) {place_flag[x]=-1;place[x]=-1;}
            }
            used_col[i]=0;
            pos_col[d]=-1;
        }        
        return false;
    }
    
    bool go_row(int d)//
    {
        if(d==9) return go_col(0);
        pii range=get_range(d,0);
        for(int i=range.first;i<=range.second;i++) 
        {
            if(!used_row[i]) 
            {
                used_row[i]=1;
                pos_row[d]=i;
                if(go_row(d+1)) return true;
                used_row[i]=0;
                pos_row[d]=-1;
            }
        }    
        return false;
    }
    
    bool work()
    {
        for(int i=0;i<4;i++)
        {
            init();
            rotate();
            if(go_row(0)) return true; 
        }
        return false;
    }
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            for(int i=0;i<9;i++)
            {
                cin>>s;
                for(int j=0;j<9;j++)
                {
                    b[i][j]=s[j]-'0';
                }
            }
            for(int i=0;i<9;i++)
            {
                cin>>s;
                for(int j=0;j<9;j++)
                {
                    c[i][j]=s[j]-'0';
                }
            }
            if(work()) printf("Yes
    "); else printf("No
    ");
        }
        return 0;
    }
  • 相关阅读:
    在Eclipse中运行JAVA代码远程操作HBase的示例
    hbase基本概念和hbase shell常用命令用法
    如何使用putty远程连接linux
    如何在Eclipse下安装SVN插件——subclipse
    solr之创建core(搜索核心,包括索引和数据)的方法
    百度地图api基本用法
    四年大学不如选择培训一年?
    树常见的算法操作
    二叉树常见遍历算法
    Java多线程实现生产者消费者延伸问题
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6021040.html
Copyright © 2020-2023  润新知