hdu 3909 数独扩展

思路:做法与9*9的一样。只不过是变量。

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define Maxn 4100
#define Maxm 200010
#define Y 1100
#define LL __int645rssss
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 100000
#define lowbit(x) (x&(-x))
#define clr(x,y) memset(x,y,sizeof(x))
#define Mod 1000000007
using namespace std;
int H[Maxn],R[Maxn*Y],L[Maxn*Y],D[Maxn*Y],U[Maxn*Y],Q[Maxn*Y],X[Maxn*Y],C[Maxn*Y],S[Maxn*Y];
int cnt,n,g[17][17],id,N,num;
void init(int n)
{
    int i;
    for(i=0;i<=n;i++){
        R[i]=i+1;
        L[i+1]=i;
        U[i]=D[i]=i;
        S[i]=0;
    }
    clr(H,-1);
    R[n]=0;
    id=n+1;
}
void ins(int r,int c)
{
    U[id]=c;
    D[id]=D[c];
    U[D[c]]=id;
    D[c]=id;
    S[c]++;
    if(H[r]<0)
        H[r]=R[id]=L[id]=id;
    else {
        R[id]=R[H[r]];
        L[id]=H[r];
        L[R[H[r]]]=id;
        R[H[r]]=id;
    }
    C[id]=c;
    X[id++]=r;
}
void Remove(int c)
{
    R[L[c]]=R[c];
    L[R[c]]=L[c];
    for(int i=D[c];i!=c;i=D[i]){
        for(int j=R[i];j!=i;j=R[j]){
            D[U[j]]=D[j];
            U[D[j]]=U[j];
            S[C[j]]--;
        }
    }
}
void Resume(int c)
{
    R[L[c]]=c;
    L[R[c]]=c;
    for(int i=D[c];i!=c;i=D[i]){
        for(int j=R[i];j!=i;j=R[j]){
            U[D[j]]=j;
            D[U[j]]=j;
            S[C[j]]++;
        }
    }
}
bool dfs(int step,int f)
{
    int i,k,c,j,temp;
    temp=inf;
    if(R[0]==0) {
        num=step;
        if(cnt||f){
        cnt++;
        return true;
        }
        cnt++;
        return false;
    }
    for(i=R[0];i;i=R[i]) if(S[i]<temp){
        temp=S[i];
        c=i;
    }
    Remove(c);
    for(i=D[c];i!=c;i=D[i]){
        Q[step]=X[i];
        for(j=R[i];j!=i;j=R[j]){
            Remove(C[j]);
        }
        if(dfs(step+1,f))
            return true;
        for(j=L[i];j!=i;j=L[j]){
            Resume(C[j]);
        }
    }
    Resume(c);
    return false;
}
void build()
{
    int i,j,k;
    int r,c;
    init(N*N*4);
    for(i=1;i<=N;i++){
        for(j=1;j<=N;j++){
            if(g[i][j]){
                r=(i-1)*N*N+(j-1)*N+g[i][j];
                c=(i-1)*N+g[i][j];
                ins(r,c);
                c=N*N+(j-1)*N+g[i][j];
                ins(r,c);
                c=2*N*N+(i-1)*N+j;
                ins(r,c);
                c=3*N*N+((i-1)/n*n+(j+n-1)/n-1)*N+g[i][j];
                ins(r,c);
            }
            else{
                for(k=1;k<=N;k++){
                r=(i-1)*N*N+(j-1)*N+k;
                c=(i-1)*N+k;
                ins(r,c);
                c=N*N+(j-1)*N+k;
                ins(r,c);
                c=2*N*N+(i-1)*N+j;
                ins(r,c);
                c=3*N*N+((i-1)/n*n+(j+n-1)/n-1)*N+k;
                ins(r,c);
                }
            }
        }
    }
}
void solve()
{
    int i,j,k,r,c;
    cnt=0;
    build();
    dfs(0,0);
    if(!cnt) {
        printf("No Solution\n");
        return;
    }
    if(cnt==2){
        printf("Multiple Solutions\n");
        return;
    }
    for(i=1;i<=N;i++){
        for(j=1;j<=N;j++){
            if(!g[i][j]) continue;;
            c=g[i][j];
            g[i][j]=0;
            cnt=0;
            build();
            dfs(0,0);
            if(cnt<2)
                break;
            g[i][j]=c;
        }
        if(j<=N) break;
    }
    if(i<=N){
        printf("Not Minimal\n");
        return;
    }
    cnt=0;
    build();
    dfs(0,1);
    for(i=0;i<num;i++){
        r=(Q[i]-1)/(N*N)+1;
        c=(Q[i]-(r-1)*(N*N)-1)/N+1;
        k=(Q[i]-1)%N+1;
        g[r][c]=k;
    }
    for(i=1;i<=N;i++){
        for(j=1;j<=N;j++){
            if(g[i][j]<10)
                printf("%d",g[i][j]);
            else{
                printf("%c",'A'+g[i][j]-10);
            }
        }
        printf("\n");
    }
}
int main()
{
    int i,j,k;
    char str[20];
    while(scanf("%d",&n)!=EOF){
        clr(g,0);
        N=n*n;
        for(i=1;i<=N;i++){
            scanf("%s",str);
            for(j=0;j<N;j++) if(str[j]!='.'){
                if(str[j]<='9'&&str[j]>='0')
                g[i][j+1]=str[j]-'0';
                else
                g[i][j+1]=str[j]-'A'+10;
            }
        }
        solve();
    }
    return 0;
}

 

posted @ 2013-09-20 20:12  fangguo  阅读(177)  评论(0编辑  收藏  举报