• UVA10957 So Doku Checker


    原题链接

    题意简述

    有若干个数据,每次会给你一个 (9 imes 9) 的数独,你需要补全这个数独。其中 (1) ~ (9) 表示已经确定的数,(0) 代表不确定的数,也就是你要填的数。(数独规则请自行百度

    如果输入的数独已经不符合规则,输出“Illegal”;如果有唯一解,输出“Unique”;如果有多组解,输出“Ambiguous”;如果无解,输出“Impossible”。(注意是 illegal,只是第一个 i 大写了

    题目分析

    对于数独一类的问题以及如此小的数据范围(虽然没有说有多少组数据),考虑暴力搜索。

    首先特判 Illegal 的情况,对每一行每一列每一个宫格开个桶检查一遍,不符合就直接输出。

    然后从 ((1,1)) 开始搜索,每次搜索到一个点就判断这一列这一行和这一宫格已经有了哪些数,再选择没出现过的数往下搜索。如果没有就返回。

    到了 ((9,9)) 如果符合要求,就说明有一个解。最后判断解的个数就可以了。

    由于有数独的规则,搜索的很大一部分其实都被剪枝掉了,所以时间是可以接受的。

    注意几点:

    • 输出格式要按题目要求(其实看样例输出就懂了)。

    • 如果到了每一行的尽头,就要到下一行开始搜索(其实搜索顺序没所谓,我这里是一行一行搜)。

    • 如果这个数原本是空的(即为0),那么返回的时候也要赋回0。

    • 每次检查要把桶清零,或者定义局部变量。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    namespace my_std{
    	#define ll long long 
    	#define bl bool
    	#define pf printf
    	#define pc putchar
    	#define fr(i,x,y) for(register ll i=(x);i<=(y);i++)
    	#define il inline
    	il ll read(){
    		ll sum=0,f=1;
    		char ch=0;
    		while(!isdigit(ch)){
    			if(ch=='-') f=-1;
    			ch=getchar();
    		}
    		while(isdigit(ch)){
    			sum=sum*10+(ch^48);
    			ch=getchar();
    		}
    		return sum*f;
    	}
    }
    using namespace my_std;
    ll a[11][11],cnt=0,ans=0;
    bl ck[11],pd;
    void dfs(ll x,ll y){
    	if(a[x][y]){//如果已经有值 
    		if(x==9&&y==9) ans++;
    		else if(y==9) dfs(x+1,1);
    		else dfs(x,y+1);
    		return;
    	}
    	bl ckk[11];
    	memset(ckk,0,sizeof(ckk));
    	fr(i,1,9){//检查行/列 
    		ckk[a[x][i]]=1;
    		ckk[a[i][y]]=1;
    	}
    	fr(i,3*((x-1)/3)+1,3*((x-1)/3)+3) fr(j,3*((y-1)/3)+1,3*((y-1)/3)+3) ckk[a[i][j]]=1;//检查宫格 
    	fr(i,1,9){
    		if(!ckk[i]){//判断可以填哪些数 
    			a[x][y]=i;
    			if(x==9&&y==9) ans++;
    			else if(y==9) dfs(x+1,1);
    			else dfs(x,y+1);
    			a[x][y]=0;//赋回0 
    		}
    	}
    }
    int main(){
    	while(~scanf("%lld",&a[1][1])){
    		ans=0;
    		cnt++;
    		fr(i,1,9) fr(j,1,9) if(i!=1||j!=1) a[i][j]=read();
    		pd=0;
    		fr(i,1,9){//检查每一行 
    			memset(ck,0,sizeof(ck));
    			fr(j,1,9){
    				if(ck[a[i][j]]&&a[i][j]) pd=1;
    				ck[a[i][j]]=1;
    			}
    		}
    		fr(i,1,9){//检查每一列 
    			memset(ck,0,sizeof(ck));
    			fr(j,1,9){
    				if(ck[a[j][i]]&&a[j][i]) pd=1;
    				ck[a[j][i]]=1;
    			}
    		}
    		for(ll i=1;i<=9;i+=3){//检查每一宫格 
    			for(ll j=1;j<=9;j+=3){
    				memset(ck,0,sizeof(ck));
    				fr(ii,i,i+2){
    					fr(jj,j,j+2){
    						if(ck[a[ii][jj]]&&a[ii][jj]) pd=1;
    						ck[a[ii][jj]]=1;
    					}
    				}
    			}
    		}
    		if(pd){
    			pf("Case %lld: Illegal.
    ",cnt);
    			continue;
    		}
    		dfs(1,1);
    		if(!ans) pf("Case %lld: Impossible.
    ",cnt);
    		else if(ans==1) pf("Case %lld: Unique.
    ",cnt);
    		else pf("Case %lld: Ambiguous.
    ",cnt);
    	}
    }
    
  • 相关阅读:
    css 父层 透明 子层不透明Alpha
    ecshop循环foreach,iteration,key,index
    ecshop变量介绍
    ecshop 获取某个商品的 所有订单信息 或者销量
    echosp 销量排行 新增实际价格
    ecshop后台模板设置中将非可编辑区改为可编辑区
    ecshop 影响全局的标量lib_main.php
    个人js
    fixed的left:50%,漂浮
    js返回顶部
  • 原文地址:https://www.cnblogs.com/LZY-LZY/p/15239888.html
Copyright © 2020-2023  润新知