和数独1差不多--dancing link算法等会学完会有博客的QAQ,下面是爆搜解法.
数独1的代码也就1百多行QWQ,数独2也才200多行,可惜蒟蒻代码打的少,导致码力十分弱,所以写下博客为自己壮胆QAQ.
数独2题目是:
请你将一个16x16的数独填写完整,使得每行、每列、每个4x4十六宫格内字母A~P均恰好出现一次。保证每个输入只有唯一解决方案。
也就是按题目模拟以及爆搜即可.
下面讲下剪枝:
剪枝1:对于每个空格假如填不了任何字母则无解,假如只能填一个字母那就直接填这个字母.
剪枝2:对于每一行而言,假如每个字母不能出现在任何一个位子则无解.假如那个位子只能填一个字母则直接填上.
剪枝3:对于每一列而言,假如每个字母不能出现在任何一个位子则无解.假如那个位子只能填一个字母则直接填上.
剪枝4:对于每个16宫格而言,假如每个字母不能出现在任何一个位子则无解.假如那个位子只能填一个字母则直接填上.
剪枝5:每次选择空格时,选择方案数最小的来填.
emmm...下面就到了艰难的代码时刻QAQ

#include <bits/stdc++.h>
using namespace std;
const int N=16;
int mp[1<<(N+1)+1],ones[1<<(N+1)+1],state[N+1][N+1],bstate[N*N+1][N+1][N+1],bstate2[N*N+1][N+1][N+1];
char str[N][N+1],bstr[N*N+1][N+1][N+1];
void init()
{
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            state[i][j]=(1<<N)-1;
        }
    }
}

inline int lowbit(int x)
{
    return x&(-x);
}

void draw(int x,int y,int c)
{
    str[x][y]='A'+c;
    for(int i=0;i<N;i++)
    {
          state[x][i]&=~(1<<c);
          state[i][y]&=~(1<<c);
    }
    int sx=x/4*4,sy=y/4*4;
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            state[sx+i][sy+j]&=~(1<<c);
        }
    }
    state[x][y]=1<<c;
}

bool dfs(int cnt)
{
    if(!cnt) return true;
    int bcnt=cnt;
    memcpy(bstr[bcnt],str,sizeof str);
    memcpy(bstate[bcnt],state,sizeof state);
    //剪枝1:
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(str[i][j]=='-')
            {
                if(!state[i][j])
                {
                    memcpy(state,bstate[bcnt],sizeof state);
                    memcpy(str,bstr[bcnt],sizeof str);
                    return false;
                }
                if(ones[state[i][j]]==1)
                {
                    draw(i,j,mp[state[i][j]]);
                    cnt--;
                }
            }

        }
    }
    //剪枝2:
    for(int i=0;i<N;i++)//枚举每一行
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举每一行的每一个数
        {
            sand&=~(state[i][j]&s);//排除多个选择的数
            s|=state[i][j];//看下是否全部覆盖
            if(str[i][j]!='-') ck|=state[i][j];//排除已经填过的数

        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    if (state[i][k]&t)
                    {
                        draw(i,k,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝3:
    for(int i=0;i<N;i++)//枚举每一列
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举每一行的每一个数
        {
            sand&=~(state[j][i]&s);//排除多个选择的数
            s|=state[j][i];//看下是否全部覆盖
            if(str[j][i]!='-') ck|=state[j][i];//排除已经填过的数
        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    if (state[k][i]&t)
                    {
                        draw(k,i,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝4:
    for(int i=0;i<N;i++)//枚举16宫格的编号
    {
        int ck=0;int s=0;int sand=(1<<N)-1;
        for(int j=0;j<N;j++)//枚举在16宫格的每个位子
        {
            int sx=i/4*4,sy=i%4*4;
            int dx=j/4,dy=j%4;
            sand&=~(state[sx+dx][sy+dy]&s);//排除多个选择的数
            s|=state[sx+dx][sy+dy];//看下是否全部覆盖
            if(str[sx+dx][sy+dy]!='-') ck|=state[sx+dx][sy+dy];//排除已经填过的数
        }
        if(s!=(1<<N)-1)
        {
             memcpy(state,bstate[bcnt],sizeof state);
             memcpy(str,bstr[bcnt],sizeof str);
             return false;
        }
        for(int j=sand;j;j-=lowbit(j))
        {
            int t=lowbit(j);
            if(!(t&ck))
            {
                for(int k=0;k<N;k++)
                {
                    int sx=i/4 *4,sy=i%4*4;
                    int dx=k/4,dy=k%4;
                    if (state[sx+dx][sy+dy]&t)
                    {
                        draw(sx+dx,sy+dy,mp[t]);
                        cnt--;
                        break;
                    }
                }
            }
        }
    }
    //剪枝5:
    int x,y,sum=30;
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(str[i][j]=='-'&&ones[state[i][j]]<sum)
            {
                sum=ones[state[i][j]];
                x=i,y=j;
            }
        }
    }
    if(!cnt) return true;
    memcpy(bstate2[bcnt],state,sizeof state);
    for (int i = state[x][y]; i; i -= lowbit(i))
    {
        memcpy(state,bstate2[bcnt],sizeof state);
        draw(x,y,mp[lowbit(i)]);
        if(dfs(cnt - 1)) return true;
    }
    memcpy(state,bstate[bcnt],sizeof state);
    memcpy(str,bstr[bcnt],sizeof str);
    return false;
}

int main()
{
    for(int i=0;i<N;i++) mp[1<<i]=i;
    for(int i=1;i<1<<N;i++)
    {
        for(int j=i;j;j-=lowbit(j))
        {
            ones[i]++;
        }
    }
    while(cin>>str[0])
    {
>         int cnt=0;
        for(int i=1;i<N;i++) cin>>str[i];
        init();
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<N;j++)
            {
                if(str[i][j]!='-')
                {
                    draw(i,j,str[i][j]-'A');
                }
                else cnt++;
            }
        }
        dfs(cnt);
        for(int i=0;i<N;i++) cout<<str[i]<<endl;
        cout<<endl;
    }
    return 0;
}

感谢帮我debug的大佬