蓝桥杯 拉丁方块

一开始也是没什么头绪 强上了DFS 没想到还成了
主要注意 一定要在返回前面的格子时要初始化当前格子

#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
using namespace std;

int divide[6][6]=
{
0,0,0,0,1,1,
0,2,2,0,1,3,
2,2,1,1,1,3,
2,4,3,3,3,3,
2,4,4,4,5,5,
4,4,5,5,5,5
};
int alphav[6][6]={0};//记录每个区域字符的使用情况 第一行代表第一个区域 
int visited[6][6]={0};//用来判断该格子是否填有字符 
char table[6][6];//记录 
char alpha[6]={'A','B','C','D','E','F'};
struct Point{
	int x;
	int y;
	Point(int _x,int _y)
	{
		x=_x;
		y=_y;
	};
};


void print()
{
	for(int i=0;i<6;i++)
	{
		for(int j=0;j<6;j++)
		{
			printf("%c ",table[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

int check(int x,int y)
{
	for(int j=0;j<6;j++)
	{
		if(j==y)continue;
		if(table[x][j]==table[x][y])return 0;//判断行是否满足 
	}
	
	for(int i=0;i<6;i++)
	{
		if(i==x)continue;
		if(table[x][y]==table[i][y])return 0;//判断列是否满足 
	}
	
	return 1;//都满足返回一 
 } 

void dfs(int x,int y)
{	

	
	if(y==6)
	{
		x++;y=0;//到第六个换行 
	}
	
	if(visited[x][y]==1)
	{
		dfs(x,y+1);//如果是预先填好的跳过 
	}
	
	if(x==6)
	{
		print();
		return ;
	}
	//printf("%d %d\n",x,y);print();
	for(int i=0;i<6;i++)
	{
		if(visited[x][y]==0&&alphav[divide[x][y]][i]==0)
		{
			table[x][y]=alpha[i];//逐一试探字母 
			if(check(x,y)==1)//不冲突 
			{
			alphav[divide[x][y]][i]=1;
			visited[x][y]=1;
			dfs(x,y+1);
			alphav[divide[x][y]][i]=0;
			visited[x][y]=0;//回来后改变的值都要初始化 
			
			table[x][y]='0';//※注意这个也要初始化因为返回上一步当前试探的字母也要删除 
			}
			else 
			{
			table[x][y]='0';//不合适要去掉试探的字母 
			continue;
			}
			
		} 
	}
}

int main()
{
   for(int i=0;i<6;i++)
  {
	char temp[10];
	scanf("%s",temp);
	for(int j=0;j<6;j++)
	{
		divide[i][j]=temp[j]-'0';
	}
  }
    for(int i=0;i<6;i++)
  for(int j=0;j<6;j++) table[i][j]='0'; //先初始化装字母的表 
	
 
int n;cin>>n;
printf("输入预填字母:\n");
for(int i=0;i<n;i++)
{
	char temp[10];
	scanf("%s",temp);
	table[temp[0]-'0'][temp[1]-'0']=temp[2];
	visited[temp[0]-'0'][temp[1]-'0']=1;
	alphav[divide[temp[0]-'0'][temp[1]-'0']][temp[2]-'A']=1;
	//printf("---\n%c %d %d\n",table[temp[0]-'0'][temp[1]-'0'],visited[temp[0]-'0'][temp[1]-'0'],alphav[divide[temp[0]-'0'][temp[1]-'0']][temp[2]-'A']);
}//由于有预先填的  所以要修改各个表 
	/*table[0][2]='C';visited[0][2]=1;alphav[divide[0][2]][2]=1;
	table[0][3]='B';visited[0][3]=1;alphav[divide[0][3]][1]=1;
	table[0][5]='A';visited[0][5]=1;alphav[divide[0][5]][0]=1;
	table[2][0]='D';visited[2][0]=1;alphav[divide[2][0]][3]=1;
	table[3][5]='E';visited[3][5]=1;alphav[divide[3][5]][4]=1;
	table[5][3]='F';visited[5][3]=1;alphav[divide[5][3]][5]=1;*/
	
	
	dfs(0,0);
	return 0;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值