zoukankan      html  css  js  c++  java
  • [NOIP 2009]靶形数独题解

    题目链接:点击

    题目的一些信息就不给了,点链接吧

    解题思路:

    我总结为一个要点,一个优化:

    要点:搜索顺序不能

    for(i=1;i<=9;i++)
    
    for(j=1;j<=9;j++)

    这样时间复杂度过不去。

    如何搜索?

    当做填数字一样,每一个格子枚举数组,从上到下,从左到右填过去。

    优化这真的是欺负我这种没有玩过数独的人。

    从已经填数字多的一行填,对行排个序,虽然每个格子都要填,这样每个格子能够搜索的状态数总体变少了,就行了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define R register int 
    #define L inline int
    using namespace std;
    const int N=10;
    int a[N][N],line[N][N],list[N][N],nine[N][N];
    int ans,flag,ned,cnt;
    struct T{
        int p,w;
    }o[N*N];
    bool cmp(T qq,T ee){
        return qq.w>ee.w;
    }
    L judge(R x,R y){
        if(x<=3){
            if(y<=3)return 1;
            if(y>=7)return 3;
            return 2;
        }
        if(x<=6&&x>=4){
            if(y<=3)return 4;
            if(y>=7)return 6;
            return 5;
        }
        else
        {
            if(y<=3)return 7;
            if(y>=7)return 9;
            return 8;
        }
    }
    L pd(R x,R y){
        if(x==1||y==1||x==9||y==9)return 6;
        if(x==2||y==2||x==8||y==8)return 7;
        if(x==3||y==3||x==7||y==7)return 8;
        if(x==4||y==4||x==6||y==6)return 9;
        return 10;
    }
    inline void dfs(R num,R tot,R x,R y){
        if(num==81){
        flag=1;
        ans=max(tot,ans);
        return;
        }
        if(y==10)
        dfs(num,tot,x+1,1);
        else
        if(a[o[x].p][y])
        dfs(num,tot,x,y+1);
        else
        {
            R root=judge(o[x].p,y);
        for(R i=1;i<=9;++i){
            if(!line[o[x].p][i]&&!list[y][i]&&!nine[root][i]){
               line[o[x].p][i]=list[y][i]=nine[root][i]=1;
               if(num==81){
               flag=1;
               ans=max(tot,ans);
               line[o[x].p][i]=list[y][i]=nine[root][i]=0;
               return;
              }
               dfs(num+1,tot+i*pd(o[x].p,y),x,y+1);
               line[o[x].p][i]=list[y][i]=nine[root][i]=0;
            }
        }
        }
    }
    int main(){
        for(R i=1;i<=9;++i)
        for(R j=1;j<=9;++j){
        o[i].p=i;
        scanf("%d",&a[i][j]);
        if(a[i][j]){
        cnt++;
        o[i].w++;
        ans+=pd(i,j)*a[i][j];
        line[i][a[i][j]]=1;
        list[j][a[i][j]]=1;
        nine[judge(i,j)][a[i][j]]=1;
        }
        }
        sort(o+1,o+9+1,cmp);
        ned=ans;
        dfs(cnt,ned,1,1);
        if(!flag)
        printf("-1");
        else
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    在win7 64位上安装VS2015的问题汇总
    关于C#类的深拷贝的问题
    线程、进程
    c#日志 log4net
    C#常识
    Tribon数据抽取的一些心得
    Java Web相关课程学习笔记
    过滤器、监听器、拦截器的区别
    SHH架构中几个配置文件解释 applicationContext.xml web.xml struts.xml
    vue关于动态增加路由页面
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9715236.html
Copyright © 2011-2022 走看看