zoukankan      html  css  js  c++  java
  • 【NOIP2009】靶形数独

    搜索绝对是解决数独问题的一大利器。

    我们将不完整的数独读入。如果爆搜的话显然凉凉O(2^81)?

    想一下人类在玩数独的时候会怎样——找出填数比较多的行与列的交点,因为这样能排除更多的非法选择。

    放到搜索上就能减小搜索树的规模,降低时间复杂度。

    我们统计每一行、每一列已经填完的数的数量,再统计每一行、每一列、每一小区域当中某一个数是否出现。

    每一次填数之前,找已经填数最多的一行与最多的一列的交点填(如果还没填的话),当数独都填完了以后统计一下得分即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[10][10],h[10][10],s[10][10],f[10][10];
     4 int hnum[10],snum[10];
     5 int ans=-1,num; 
     6 int calc(int i,int j)
     7 {
     8     return (i-1)/3*3+1+(j-1)/3;
     9 }
    10 int sum[10][10]=
    11 {
    12     {0,0,0,0,0,0,0,0,0,0},
    13     {0,6,6,6,6,6,6,6,6,6},
    14     {0,6,7,7,7,7,7,7,7,6},
    15     {0,6,7,8,8,8,8,8,7,6},
    16     {0,6,7,8,9,9,9,8,7,6},
    17     {0,6,7,8,9,10,9,8,7,6},
    18     {0,6,7,8,9,9,9,8,7,6},
    19     {0,6,7,8,8,8,8,8,7,6},
    20     {0,6,7,7,7,7,7,7,7,6},
    21     {0,6,6,6,6,6,6,6,6,6},
    22 };
    23 inline int total()
    24 {
    25     int aaa=0;
    26     for(int i=1;i<=9;i++)
    27         for(int j=1;j<=9;j++)
    28             aaa+=a[i][j]*sum[i][j];
    29     return aaa;
    30 }
    31 void dfs(int x,int y,int z)
    32 {
    33     if(z==81)
    34     {
    35         ans=max(ans,total());
    36         return ;
    37     }
    38     for(int k=1;k<=9;k++)
    39     {
    40         if(h[x][k]||s[y][k]||f[calc(x,y)][k]) continue ;
    41         h[x][k]=1;
    42         s[y][k]=1;
    43         f[calc(x,y)][k]=1;
    44         a[x][y]=k;
    45         hnum[x]++;
    46         snum[y]++;
    47         int xx=0,yy=0;
    48         int maxx=-1,maxy=-1;
    49         for(int i=1;i<=9;i++)
    50             if(hnum[i]>maxx&&hnum[i]<9) maxx=hnum[i],xx=i;
    51         for(int j=1;j<=9;j++)
    52             if(snum[j]>maxy&&!a[xx][j]) maxy=snum[j],yy=j;
    53         dfs(xx,yy,z+1);
    54         h[x][k]=0;
    55         s[y][k]=0;
    56         f[calc(x,y)][k]=0;
    57         hnum[x]--;
    58         snum[y]--;
    59         a[x][y]=0;
    60     }
    61 }
    62 int main()
    63 {
    64     ios::sync_with_stdio(false);
    65     for(int i=1;i<=9;i++)
    66         for(int j=1;j<=9;j++)
    67         {
    68             cin>>a[i][j];
    69             if(a[i][j]!=0)
    70             {
    71                 h[i][a[i][j]]=1;
    72                 s[j][a[i][j]]=1;
    73                 f[calc(i,j)][a[i][j]]=1;
    74                 num++;
    75                 hnum[i]++;
    76                 snum[j]++;
    77             }
    78         }
    79     int x=0,y=0,maxx=-1,maxy=-1;
    80     for(int i=1;i<=9;i++)
    81         if(hnum[i]>maxx&&hnum[i]<9) maxx=hnum[i],x=i;
    82     for(int j=1;j<=9;j++)
    83         if(snum[j]>maxy&&!a[x][j]) maxy=snum[j],y=j;
    84     dfs(x,y,num);
    85     cout<<ans;
    86     return 0;
    87 }
    AC Code
  • 相关阅读:
    【最短路】The 2019 Asia Nanchang First Round Online Programming Contest Fire-Fighting Hero (Dijkstra)
    【积累】The 2019 Asia Nanchang First Round Online Programming Contest The Nth Item (矩阵快速幂 k进制快速幂)
    【线段树】The Preliminary Contest for ICPC Asia Xuzhou 2019 Colorful String(回文树+线段树+状压/bitset)
    allure参数说明及代码示例
    Idea+maven+testng+reportng生成测试报告
    ubuntu 16.04 镜像下载
    new AndroidDriver报错java.lang.NoSuchMethodError: com.google.common.base.Throwables.throwIfUnchecked
    Appium常用的API
    Appium常用的定位方法
    adb 指令总结
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10583888.html
Copyright © 2011-2022 走看看