Sudoku Extension UVALive - 4763 搜索

题目:思路非常明确, 九宫的深搜 ,一开始写的时候一直是wa,因为在从当前行换到下一行的时候坐标变换一直有问题,学习了大神的一个变量的深搜,然后转换成坐标的办法。  


#include <bits/stdc++.h>

using namespace std;

const int N = 12; 
char mp[N][N]; 
int row[N][N],col[N][N]; 
int flag[N][N]; 
int vis[30]; 
int t,ans; 

void dfs( int k )
{
	if ( k==81 ) {
		++ans; return ; 
	}
	int x = k/9,y = k%9; 
	if ( mp[x][y]>='1' && mp[x][y]<='9' ) {
		dfs( k+1 ) ; 
	} else if ( mp[x][y]=='0' ) {
		for ( int i=1; i<=9; i++ ) {
				if ( row[x][i] || col[y][i] || flag[x/3*3+y/3][i] ) continue;
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 1; 
				dfs( k+1 ) ; 
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 0; 
		}
	} else if ( mp[x][y]=='e' ) {
		for ( int i=2; i<=9; i+=2 ) {
				if ( row[x][i] || col[y][i] || flag[x/3*3+y/3][i] ) continue;
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 1; 
				dfs( k+1 ) ; 
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 0; 
		}
	} else if ( mp[x][y]=='o' ) {
		for ( int i=1; i<=9; i+=2 ) {
				if ( row[x][i] || col[y][i] || flag[x/3*3+y/3][i] ) continue;
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 1; 
				dfs( k+1 ) ; 
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 0; 
		}
	} else {
		if ( vis[mp[x][y]-'a'] ) {
			int i = vis[mp[x][y]-'a'] ; 
			if ( row[x][i] || col[y][i] || flag[x/3*3+y/3][i] ) return ;
			row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 1; 
			dfs( k+1 ) ; 
			row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 0; 
		} else {
			for ( int i=1; i<=9; i++ ) {
				if ( row[x][i] || col[y][i] || flag[x/3*3+y/3][i] ) continue;
				vis[ mp[x][y]-'a' ] = i ; 
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 1; 
				dfs( k+1 ) ; 
				row[x][i] = col[y][i] = flag[x/3*3+y/3][i] = 0; 
				vis[ mp[x][y]-'a' ] = 0 ; 
			}
		}
	}
}

int main()
{
	cin>>t; 
	while( t-- )
	{
		memset( vis,0, sizeof vis ); 
		memset( flag,0,sizeof flag); 
		memset( row,0,sizeof row ) ; 
		memset( col,0,sizeof col );  
		for ( int i=0; i<9; i++ ) scanf("%s",mp[i]); 
		for ( int i=0; i<9; i++ ) 
		{	for ( int j=0; j<9; j++ ) {
				if ( mp[i][j]>='1' && mp[i][j]<='9' ) {
					row[i][mp[i][j]-'0'] = 1; 
					col[j][mp[i][j]-'0'] = 1; 
					flag[i/3*3+j/3][mp[i][j]-'0'] = 1; 
				}
			}
		}
		ans = 0 ; 
		dfs( 0 ); 
		cout<<ans<<endl; 
	}
	return 0; 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值