首页 > 代码库 > 靶形数独

靶形数独

搜索,据说反着输入有奇效,要用位运算,然后剪不剪枝无所谓,没提速。

#include<iostream>
#include<cstdio>
using namespace std;
int ans,tot,sum,sum1;
bool flag;
int board[10][10],val[10][10],squre[6][6];
int row[10],col[10];
inline int Max(int x,int y)
{
    return x>y?x:y;
}
inline int calc()
{
    int ret=0;
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++) ret+=val[i][j]*board[i][j];
    }
    return ret;
}

void dfs(int x,int y)
{    
    if(tot+sum*9*9+sum1<ans) return;
//    cout<<x<<" "<<y<<endl;
    if(x==8&&y==9)
    {
        flag=true;
        ans=Max(ans,tot+sum1);
//        cout<<"a"<<endl;
        return;
    }
    if(y==9)
    {
        dfs(x+1,0);
        return;
    }    
    
    if(board[x][y])
    {
        dfs(x,y+1);
        return;
    }

    for(int i=1;i<=9;i++)
    {
        if(!(row[x]&(1<<i))&&!(col[y]&(1<<i))&&!(squre[x/3][y/3]&(1<<i))) 
        {
            board[x][y]=i;
            sum--;
            squre[x/3][y/3]^=(1<<i);
            row[x]^=(1<<i);
            col[y]^=(1<<i);
            tot+=val[x][y]*i;
            dfs(x,y+1);
            sum++;
            squre[x/3][y/3]^=(1<<i);
            row[x]^=(1<<i);
            col[y]^=(1<<i);
            tot-=val[x][y]*i;
            board[x][y]=0;
        }
    }
}
int main()
{
    for(int i=0;i<9;i++)
    {
        val[0][i]=val[i][0]=val[8][i]=val[i][8]=6;
    }
    for(int i=1;i<8;i++)
    {
        val[1][i]=val[i][1]=val[7][i]=val[i][7]=7;
    }
    for(int i=2;i<7;i++)
    {
        val[2][i]=val[i][2]=val[6][i]=val[i][6]=8;
    }
    for(int i=3;i<6;i++)
    {
        val[3][i]=val[i][3]=val[5][i]=val[i][5]=9;
    } 
    val[4][4]=10;
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            scanf("%d",&board[i][j]); 
            sum+=board[i][j]==0;
            sum1+=board[i][j]*val[i][j];
            row[i]^=(1<<board[i][j]);
            col[j]^=(1<<board[i][j]);
            squre[i/3][j/3]^=(1<<board[i][j]);
        }
    } 
    ans=sum1;
    dfs(0,0);
    if(!flag) cout<<-1<<endl; else
    cout<<ans<<endl;
    return 0;
} 

 

靶形数独