数独游戏(9*9)

题目

英文题目

在这里插入图片描述

中文题目

在这里插入图片描述

输入样例

.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end

输出样例

527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936

能过的是题解四,往下扒拉吧

题解一:DFS(1000ms会超时)

#include <bits/stdc++.h>
using namespace std;
int P[9][9];
bool flag = false;
char s[81];
// 判断即将放入的是否符合条件 
bool check(int n, int num)
{
	// 行 ,列
	for (int i = 0; i < 9; i++)
	{
		if (P[n / 9][i] == num || P[i][n % 9] == num)
		{
			return false;
		}
	}
	// 宫
	int x = n / 9 / 3 * 3;
	int y = n % 9 / 3 * 3;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (P[x + i][y + j] == num)
			{
				return false;
			}
		}
	}
	return true;
}
void dfs(int n)
{
	// 成功 
	if (n == 81)
	{
		flag = true;
		return;
	}
	int x = n / 9, y = n % 9;
	// 有值 跳过 
	if (P[x][y])
	{
		dfs(n + 1);
		return;
	}
	// 遍历 
	for (int i = 1; i <= 9; i++)
	{
		// 判断成功 赋值  
		if (check(n, i))
		{
			P[x][y] = i;
			dfs(n + 1);
			// 退出时判断是否完成  完成时退出 
			if (flag)
			{
				return;
			}
			// 未完成 重置棋盘 
			P[x][y] = 0;
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
   
	while (scanf("%[^\n]", &s))
	{
		 getchar();
		flag = false;
		char t;
		int k = 0;
		for (int i = 0; i < 9; ++i)
			for (int j = 0; j < 9; ++j)
			{
				t = s[k]; //cout << " t1: " << t;
				if (t == '.') t = '0';
				P[i][j] = t - '0'; //cout << " t2: " << t<< " P[i][j]: " << P[i][j];
				++k;
			}
		dfs(0);
		for (int i = 0; i < 9; ++i)
			for (int j = 0; j < 9; ++j)
			{
				printf("%d",P[i][j]);
			}
		printf("\n");
	}
	return 0;
}

题解二:DFS(1000ms会超时)

#include<bits/stdc++.h>
#define scd(x) scanf("%d",&x)
#define scdd(x,y) scanf("%d %d",&x,&y)
#define sclld(x) scanf("%lld",&x)
#define sclldd(x,y) scanf("%lld %lld",&x,&y)
#define print(x) cout<<x<<endl
#define CLR(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long  ll;
const int maxn=(int)4e5+500;
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
template<typename tp>inline tp lowbit(tp x){return x&(-x);}
template<typename tp_>void debug(tp_ x) {cout<<"*********** "<<x<<" *************"<<endl;}
template<typename tp1_,typename tp2_>void debug(tp1_ x,tp2_ y){cout<<"*********** "<<x<<" "<<y<<" *************"<<endl;}
struct P{int x,y;};
char  s[100];
int a[15][15];
bool row[15][15],col[15][15],block[4][4][15];
bool judge(int x,int y,int num){
   if(!row[x][num]&&!col[y][num]&&!block[x/3][y/3][num])return true;
   else return false;
}
void dfs(int x,int y){
    int xx=x,yy=y;
    if(x>=9||y>=9){
         for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                printf("%d",a[i][j]);
            }
        }
        cout<<endl;
        return ;
    }
    if(a[x][y]){
        dfs(x+(y+1)/9,(y+1)%9);
        return ;
    }
    for(int i=1;i<=9;i++){
        if(judge(x,y,i)){
            a[xx][yy]=i;

            row[x][i]=1;
            col[y][i]=1;
            block[x/3][y/3][i]=1;
            dfs(x+(y+1)/9,(y+1)%9);
            a[xx][yy]=0;
            row[xx][i]=0;
            col[yy][i]=0;
            block[xx/3][yy/3][i]=0;
        }
    }
}
void init(){
    CLR(row);
    CLR(col);
    CLR(block);
}
void solve(){
    while(scanf("%s",s)){
        if(s[0]=='e')break;
        init();
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                int id = i*9+j;
                if(s[id]=='.'){
                    a[i][j] = 0;
                    continue;
                }
                int num=s[id]-'0';
                a[i][j] = num;
                row[i][num] = 1;
                col[j][num] = 1;
                block[i/3][j/3][num] = 1;
            }
        }
        dfs(0,0);
    }
}
int main(){
    solve();
    return 0;
}

题解三:dance link x(1000ms会超时)

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int N = 9;
const int maxn = N * N * N + 10;
const int maxnode = maxn * 4 + maxn + 10;
char g[maxn];
struct DLX
{
    int n,m,sz;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
    int H[maxn],S[maxn];
    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;
        sz = m;
        for(int i = 1;i <= n;i ++)
        {
            H[i] = -1;
        }
    }
    void Link(int r,int c)
    {
        ++ S[Col[++ sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0) H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }
   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])
            {
                ++ S[Col[U[D[j]] = D[U[j]] = j]];
            }
        }
        L[R[c]] = R[L[c]] = c;
    }
    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            for(int i = 0;i < d;i ++)
            {
                g[(ans[i] - 1) / 9] = (ans[i] - 1) % 9 + '1';
            }
            for(int i = 0;i < N * N;i ++)
            {
                printf("%c",g[i]);
            }
            printf("\n");
            return true;
        }
        int c = R[0];
        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])
        {
            ans[d] = Row[i];
            for(int j = R[i]; j != i;j = R[j]) Remove(Col[j]);
            if(Dance(d + 1)) return true;
            for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};
void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k)
{
    r = (i * N + j) * N + k;
    c1 = i * N + j + 1;
    c2 = N * N + i * N + k;
    c3 = N * N * 2 + j * N + k;
    c4 = N * N * 3 + ((i / 3) * 3 + (j / 3)) * N + k;
}
DLX dlx;
int main()
{
  //  freopen("test1","r",stdin);
    while(scanf("%s",g))
    {
		if(g=="end")return 0;
		for(int i=0;i<81;++i)
		{
			if(g[i]=='.') g[i]='0';
		}
        dlx.init(N * N * N, N * N * 4);
        int r,c1,c2,c3,c4;
        for(int i = 0;i < N;i ++)
        {
            for(int j = 0;j < N;j ++)
            {
                for(int k = 1;k <= N;k ++)
                {
                    if(g[i * N + j] == '0' || g[i * N + j] == '0' + k)
                    {
                        place(r,c1,c2,c3,c4,i,j,k);
                        dlx.Link(r,c1);
                        dlx.Link(r,c2);
                        dlx.Link(r,c3);
                        dlx.Link(r,c4);
                    }
                }
            }
        }
        dlx.Dance(0);
    }
    return 0;
}

题解四:dance link x(35ms过)

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 9 * 9 * 9 * 9 * 9 * 4 + 5;//9 * 9 * 9行9 * 9 * 4列
int s[N],h[N],u[N],d[N],l[N],r[N],col[N],row[N],ans[N];
int head,num;
char str[200];
void init()
{
    memset(s,0,sizeof(s));//记得初始化,否则TLE!!
    head = 0;
    int i;
    int c = 9 * 9 * 4;
    for(i = 0;i <= c;i ++)
    {
        u[i] = d[i] = i;
        l[i] = (i - 1 + c + 1) % (c + 1);
        r[i] = (i + 1) % (c + 1);
    }
    num = c + 1;
    memset(h,0,sizeof(h));
 
}
void insert(int i,int j)
{
    if(h[i])
    {
        r[num] = h[i];
        l[num] = l[h[i]];
        l[r[num]] = num;
        r[l[num]] = num;
    }
    else
    {
        h[i] = num;
        l[num] = r[num] = num;
    }
    s[j] ++;
    u[num] = u[j];
    d[num] = j;
    d[u[j]] = num;
    u[j] = num;
    col[num] = j;
    row[num] = i;
    num ++;
}
void del(int c)
{
    l[r[c]] = l[c];
    r[l[c]] = r[c];
    int i,j;
    for(i = d[c];i != c;i = d[i])
    {
        for(j = r[i];j != i;j = r[j])
        {
            u[d[j]] = u[j];
            d[u[j]] = d[j];
            s[col[j]] --;
        }
    }
} 
void recover(int c)
{
    int i,j;
    for(i = u[c];i != c;i = u[i])
    {
        for(j = l[i];j != i;j = l[j])
        {
            s[col[j]] ++;
            u[d[j]] = d[u[j]] = j;
        }
    }
    r[l[c]] = l[r[c]] = c;
}
bool dfs(int k)
{
    int i,j;
    if(r[head] == head)
    {
        sort(ans,ans + 81);
        for(i = 0;i < 81;i ++)
        {
            printf("%d",ans[i] - i * 9);
        }
        printf("\n");
        return true;
    }
    int mn = N;
    int c;
    for(i = r[head];i != head;i = r[i])
    {
        if(s[i] < mn)
        {
            mn = s[i];
            c = i;
        }
    }
    del(c);
    for(i = d[c];i != c;i = d[i])
    {
        ans[k] = row[i];
        for(j = r[i];j != i;j = r[j])
            del(col[j]);
        if(dfs(k + 1))
            return true;
        for(j = l[i];j != i;j = l[j])
            recover(col[j]);
    }
    recover(c);
    return false;
}
int main()
{
    while(scanf("%s",str) != EOF)
    {
        if(str[0] == 'e')
            break;
        init();
        //system("pause");
        for(int i = 0;i < strlen(str);i ++)
        {
            int rr = i / 9;
            int cc = i - rr * 9;
            int base = (rr * 9 + cc) * 9;
            if(str[i] == '.')
            {
                for(int k = 1;k <= 9;k ++)//依次填充1-9
                {
                    insert(base + k,rr * 9 + k);//第rr行填k
                    insert(base + k,81 + 9 * cc + k);//第cc列填k
                    insert(base + k,81 + 81 + (3 * (rr / 3) + cc / 3) * 9 + k);
                    insert(base + k,81 + 81 + 81 + rr * 9 + cc + 1);
                }
            }
            else
            {
                insert(base + str[i] - '0',rr * 9 + str[i] - '0');
                insert(base + str[i] - '0',81 + 9 * cc + str[i] - '0');
                insert(base + str[i] - '0',81 + 81 + (3 * (rr / 3) + cc / 3) * 9 + str[i] - '0');
                insert(base + str[i] - '0',81 + 81 + 81 + rr * 9 + cc + 1);
            }
        }
        dfs(0);
    }
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值