HDU4069(未AC)

未AC代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxnode = 100010;
const int MaxM = 1010;
const int MaxN = 1010;
int anscnt=0;
int mm[10][10];
int ansmap[10][10];
int markmap[10][10];
int vis[10][10];
struct DLX
{
    int n,m,size;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
    //U D R L用来记录某个标号的节点的上下左右节点的标号
    //Row Col用来记录某个标号的节点在矩阵中的行号和列号
    int H[MaxN], S[MaxM];
    //H是行头 S用来保存某一列中1的数量
    int ansd, ans[MaxN];
    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        //初始化列头
        for(int i = 0;i <= m;i++)
        {
            S[i] = 0;
            U[i] = D[i] = i;
            L[i] = i-1;
            R[i] = i+1;
        }
        R[m] = 0; L[0] = m;
        size = m;
        for(int i = 1;i <= n;i++)
            H[i] = -1;
    }
    void Link(int r,int c)
    {
        ++S[Col[++size]=c];
        Row[size] = r;
        D[size] = D[c];
        U[D[c]] = size;
        U[size] = c;
        D[c] = size;
        if(H[r] < 0)H[r] = L[size] = R[size] = size;
        else
        {
            R[size] = R[H[r]];
            L[R[H[r]]] = size;
            L[size] = H[r];
            R[H[r]] = size;
        }
    }
    //对某一列进行删除 同时删除列中为1的行
    void remove(int c)
    {
        L[R[c]] = L[c]; R[L[c]] = R[c];
        for(int i = D[c];i != c;i = D[i])
            for(int j = R[i];j != i;j = R[j])
            {
                U[D[j]] = U[j];
                D[U[j]] = D[j];
                --S[Col[j]];
            }
    }
    //反着恢复状态
    void resume(int c)
    {
        for(int i = U[c];i != c;i = U[i])
            for(int j = L[i];j != i;j = L[j])
            {
                U[D[j]]=D[U[j]]=j;
                ++S[Col[j]];
            }
        L[R[c]] = R[L[c]] = c;
    }
    //d为递归深度
    void Dance(int d)
    {
        if(d>81) return;
        if(anscnt>=2) return;
        if(R[0] == 0)
        {
            anscnt++;
            memcpy(ansmap,mm,sizeof(mm));
            return ;
        }
        int c = R[0];
        //一个优化  找到列中包含1最多的列 因为这样有助于减少递归深度 (很显然1多了 删掉的行也多 矩阵缩小得就快)
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        remove(c);
        //搜索
        for(int i = D[c];i != c;i = D[i])
        {
            mm[Row[i]][Col[i]]=(Row[i]-1)%9+1;
            for(int j = R[i]; j != i;j = R[j])remove(Col[j]);
            Dance(d+1);
            for(int j = L[i]; j != i;j = L[j])resume(Col[j]);
        }
        resume(c);
    }
};
DLX g;
bool haswall(int x,int y, int d)
{
    int tmp=mm[x][y]/16;
    return tmp&(1<<d);
}
void dfs(int x,int y,int id)
{
    if(vis[x][y]!=0)
        return;
    markmap[x][y]=id;
    vis[x][y]=1;
    if(!haswall(x, y, 0))
    {
        dfs(x-1,y,id);
    }
    if(!haswall(x, y, 1))
    {
        dfs(x,y+1,id);
    }
    if(!haswall(x, y, 2))
    {
        dfs(x+1,y,id);
    }
    if(!haswall(x, y, 3))
    {
        dfs(x,y-1,id);
    }

}
int main()
{
    int cas;
    scanf("%d",&cas);
    int id=1;
    for(int z=1;z<=cas;z++)
    {
        id=1;
        anscnt=0;
        memset(vis,0,sizeof(vis));
        memset(markmap,0,sizeof(markmap));
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
                scanf("%d",&mm[i][j]);
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
            {
                if(vis[i][j]==0)
                    dfs(i,j,id++);
            }
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
                mm[i][j]%=16;
        g.init(729,324);
        for(int i=1;i<=9;i++)
        {
            for(int j=1;j<=9;j++)
            {
                int id1=(i-1)*9+j;
                for(int k=1;k<=9;k++)
                {
                    if((!mm[i][j])||(mm[i][j]==k))
                    {
                        int _cx=(id1-1)*9+k;
                        g.Link(_cx,id1);
                        g.Link(_cx,81+(i-1)*9+k);
                        g.Link(_cx,2*9*9+(j-1)*9+k);
                        g.Link(_cx,3*9*9+(markmap[i][j]-1)*9+k);
                    }
                }

            }
        }
        g.Dance(0);
        printf("Case %d:\n",z);
        if(anscnt==0)
            printf("No Soltions\n");
        if(anscnt==1)
        {
            for(int i=1;i<=9;i++)
            {
                for(int j=1;j<=9;j++)
                {
                    printf("%d",ansmap[i][j]);
                }
                printf("\n");
            }
        }
        if(anscnt>1)
            printf("Multiple Solutions\n");

    }

    return 0;
}

金斌的ac代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#include<stack>
#include<queue>
using namespace std;
const int N=9;
const int mxn=N*N*N+10;
const int mxm=4*N*N+10;
const int mx=4*mxn+mxm;
struct DLX{
    int l[mx],r[mx],u[mx],d[mx];
    int x[mx],y[mx];
    int siz;
    int ansd,ans[N*N+10],gans[N*N+10];
    int h[mxn];
    int s[mxm];
    void init(int _n,int _m){
        for(int i=0;i<=_m;i++){
            u[i]=d[i]=i;
            l[i]=i-1;
            r[i]=i+1;
            s[i]=0;
        }
        for(int i=1;i<=_n;i++){
            h[i]=-1;
        }
        r[_m]=0;
        l[0]=_m;
        siz=_m;
        ansd=0;
    }
    void link(int ro,int co){
        //printf("%d %d\n",ro,co);
        x[++siz]=ro;
        y[siz]=co;
        d[siz]=co;
        u[siz]=u[co];
        u[co]=siz;
        d[u[siz]]=siz;
        s[co]++;
        if(h[ro]+1){
            int hr=h[ro];
            r[siz]=hr;
            l[siz]=l[hr];
            l[hr]=siz;
            r[l[siz]]=siz;
        }
        else h[ro]=l[siz]=r[siz]=siz;
    }
    void removc(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]){
            u[d[j]]=u[j];
            d[u[j]]=d[j];
            s[y[j]]--;
        }
    }
    void resumc(int c){
        for(int i=u[c];i!=c;i=u[i])
        for(int j=l[i];j!=i;j=l[j]){
            u[d[j]]=d[u[j]]=j;
            s[y[j]]++;
        }
        r[l[c]]=l[r[c]]=c;
    }
    void dance(int dd){
        if(dd>81){
            return ;
        }
        if(ansd>=2)return ;
        if(r[0]==0){
            ansd++;
            for(int i=1;i<=N*N;i++){
                gans[i]=ans[i];
            }
            return ;
        }
        int c=r[0];
        for(int i=r[0];i!=0;i=r[i]){
            if(s[i]<s[c])c=i;
        }
        removc(c);
        for(int i=d[c];i!=c;i=d[i]){
            ans[(x[i]-1)/N+1]=(x[i]-1)%N+1;
            for(int j=r[i];j!=i;j=r[j])removc(y[j]);
            dance(dd+1);
            for(int j=l[i];j!=i;j=l[j])resumc(y[j]);
        }
        resumc(c);
    }
}s;
int mp[N+5][N+5];
int id[N+5][N+5];
int xx[5]={-1,0,1,0};
int yy[5]={0,1,0,-1};
int w[6]={16,32,64,128,256};
int iid;
void dfs(int x,int y,int iid){
    id[x][y]=iid;
    for(int i=0;i<4;i++){
        int nx=x+xx[i];
        int ny=y+yy[i];
        if(nx>=1&&nx<=N&&ny>=1&&ny<=N&&(!id[nx][ny])){
            int f=mp[x][y]%w[i+1];
            if(f>=w[i])continue;
            dfs(nx,ny,iid);
        }
    }
}
int main(void)
{
    int t;
    while(scanf("%d",&t)!=EOF){
    for(int cas=1;cas<=t;cas++){
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++)
            scanf("%d",&mp[i][j]);
        }
        memset(id,0,sizeof(id));
        iid=0;
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                if(!id[i][j])
                dfs(i,j,++iid);
            }
        }
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                mp[i][j]%=16;
            }
        }
        s.init(N*N*N,4*N*N);
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                int id1=(i-1)*N+j;
                for(int k=1;k<=N;k++){
                    if((!mp[i][j])||(mp[i][j]==k)){
                        int _cx=(id1-1)*N+k;
                        s.link(_cx,id1);
                        s.link(_cx,N*N+(i-1)*N+k);
                        s.link(_cx,2*N*N+(j-1)*N+k);
                        s.link(_cx,3*N*N+(id[i][j]-1)*N+k);
                    }
                }
            }
        }
        printf("Case %d:\n",cas);
        s.dance(0);
        if(!s.ansd)puts("No solution");
        else if(s.ansd>1)puts("Multiple Solutions");
        else {
            for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                printf("%d",s.gans[(i-1)*N+j]);
            }
            puts("");
            }
        }
    }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值