P1074 靶形数独

题意:给你一个未完成的数独,每个位置上的价值等于数字乘上位置的价值(类似于打靶子)

  https://www.luogu.org/problemnew/show/P1074#sub

要点  1.巧妙利用打表便于搜索与判断

    2.贪心思想大量减少搜索的分支:每行(列)选0的个数少的填,减少了分支(不加此剪枝TLE一片。。。。。。)

1、刚开始别忘了加上初始的数的value

2、打表注意 0  0 都是 0,(因为打错表找了半天错。。。。QAQ)

#include<cstdio>
#include<iostream>
#include<cctype>
#include<algorithm>
using namespace std;
#define love_nmr 0
int ans=-1;
bool a[10][10];
bool b[10][10];
int value;
struct node
{
    int num;
    int id;
    friend bool operator < (const node &u,const node &v)
    {
        return u.num<v.num;
    }
}tot[10];
struct spd
{
    int x;
    int y;
    int gg;
}s[105];
int cnt;
int gong[10][10]={{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 score[10][10]={{0,0,0,0,0,0,0,0,0,0},
                   {0,6,6,6,6,6,6,6,6,6},
                   {0,6,7,7,7,7,7,7,7,6},
                   {0,6,7,8,8,8,8,8,7,6},
                   {0,6,7,8,9,9,9,8,7,6},
                   {0,6,7,8,9,10,9,8,7,6},
                   {0,6,7,8,9,9,9,8,7,6},
                   {0,6,7,8,8,8,8,8,7,6},
                   {0,6,7,7,7,7,7,7,7,6},
                   {0,6,6,6,6,6,6,6,6,6}};
bool c[10][10];
int mp[10][10];
inline void dfs(int num,int val)
{
    if(num>cnt)
    {
        ans=max(ans,val);
        return;
    }
    for(int i=1;i<=9;i++)
    {
        if(!a[s[num].x][i]&&!b[s[num].y][i]&&!c[s[num].gg][i])
        {
            a[s[num].x][i]=true;
            b[s[num].y][i]=true;
            c[s[num].gg][i]=true;
            dfs(num+1,val+i*score[s[num].x][s[num].y]);
            a[s[num].x][i]=false;
            b[s[num].y][i]=false;
            c[s[num].gg][i]=false;
        }
    }
}
int main()
{
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
        {
            scanf("%d",&mp[i][j]);
            if(mp[i][j])
            {
                a[i][mp[i][j]]=true;
                b[j][mp[i][j]]=true;
                c[gong[i][j]][mp[i][j]]=true;
                value+=mp[i][j]*score[i][j];
            }
            else
            {
                tot[i].id=i;
                tot[i].num++;
            }
        }
    sort(tot+1,tot+10);
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            if(!mp[tot[i].id][j])
            {
                s[++cnt].x=tot[i].id;
                s[cnt].y=j;
                s[cnt].gg=gong[tot[i].id][j];
            }
    dfs(1,value);
    printf("%d",ans);
    return love_nmr;
}
原文地址:https://www.cnblogs.com/olinr/p/9426766.html