zoukankan      html  css  js  c++  java
  • code1174 靶形数独

    主要是优化搜索顺序

    从选择较少的点开始,可以大大提高效率

    在search(x,y)找点的时候,对于一个空点(x y),设置一个评分score:

    score=min{ 横线x上能填的数字个数,竖线y上...个数,所在大方块中...个数 }

    选取score最小的点搜索

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    const int N = 9;
    const int Size = N+5;
    
    int ans=-1;
    int data[Size][Size];
    bool a[Size][Size],b[Size][Size],c[Size][Size];//行 列 大方格 
    int numA[Size],numB[Size],numC[Size];
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    int dic[Size][Size]={
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,1,2,2,2,3,3,3},
        {0,1,1,1,2,2,2,3,3,3},
        {0,1,1,1,2,2,2,3,3,3},
        {0,4,4,4,5,5,5,6,6,6},
        {0,4,4,4,5,5,5,6,6,6},
        {0,4,4,4,5,5,5,6,6,6},
        {0,7,7,7,8,8,8,9,9,9},
        {0,7,7,7,8,8,8,9,9,9},
        {0,7,7,7,8,8,8,9,9,9}
    };
    int len[Size]={ 0,
        8,6,4,2,1
    };
    
    int getscore(){
        int ans=0;
        int x,y;
        for(int temp=1;temp<=N/2;temp++){
            x=y=temp;
            for(int k=0;k<4;k++){
                for(int i=1;i<=len[temp];i++){
                    ans+=data[x][y]*(temp+5);
                    x+=dx[k];y+=dy[k];
                }
            }
        }
        ans+=data[5][5]*10;
        return ans;
    }
    
    void search(int& x,int& y){
        x=y=0;
        int best=999999,score;
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                if(data[i][j]==0){
                    score=min(numA[i],numB[j]);
                    score=min(score,numC[dic[i][j]]);
                    if(score<best){
                        x=i;y=j;
                        best=score;
                    }
                }
            }
        }
    }
    
    void dfs(){
        int x,y;
        search(x,y);
        if(x==0){
            ans=max(ans,getscore());
            //exit(0);
            return;
        }
        bool num[Size];
        memset(num,true,sizeof(num));
        int ff=dic[x][y];
        for(int k=1;k<=N;k++){
            if(a[x][k]==true||b[y][k]==true||c[ff][k]==true)
                num[k]=false;
        }
        for(int k=1;k<=N;k++){
            if(num[k]==true){
                data[x][y]=k;
                a[x][k]=true;b[y][k]=true;c[ff][k]=true;
                numA[x]--;numB[y]--;numC[ff]--;
                dfs();
                numA[x]++;numB[y]++;numC[ff]++;
                a[x][k]=false;b[y][k]=false;c[ff][k]=false;
                data[x][y]=0;
            }
        }
        return;
    }
    
    int main(){
        freopen("1174.in","r",stdin);
        for(int i=1;i<=9;i++)numA[i]=numB[i]=numC[i]=9;
        int x;
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                cin>>x;
                if(x!=0){
                    a[i][x]=true;numA[i]--;
                    b[j][x]=true;numB[j]--;
                    c[dic[i][j]][x]=true;numC[dic[i][j]]--;
                }
                data[i][j]=x;
            }
        }
        dfs(); 
        cout<<ans<<endl;
        
        fclose(stdin);
        return 0;
    } 
  • 相关阅读:
    android开发 退出程序
    armeabi和armeabi-v7a引起的问题
    我的博客
    第二章 应用层(一) 应用层概览
    第一章 计算机网络和因特网
    Linux学习笔记——第一篇——Ubuntu安装与操作
    怒学Python——完结篇——I/O
    怒学Python——第四篇——函数与模块
    怒学Python——第三篇——结构控制
    怒学Python——第二篇——类型与运算
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5597679.html
Copyright © 2011-2022 走看看