洛谷P1092虫食算——深搜

题目:https://www.luogu.org/problemnew/show/P1092

剪枝1:从右往左、从上往下按字母出现顺序搜索;

剪枝2:同一列前两个数字确定,可直接算出第三个数字并判断;

剪枝3:每次搜索前看看前面的列上有没有已经不符合的情况(进位最多为1);

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,c[300],jin[30];
char a[5][30];
bool vis[30],p[300];
bool check(int y)
{
	for(int i=y;i>=0;i--)
		if(p[a[1][i]]&&p[a[2][i]]&&p[a[3][i]]&&
		((c[a[1][i]]+c[a[2][i]])%n!=c[a[3][i]])&&
		((c[a[1][i]]+c[a[2][i]]+1)%n!=c[a[3][i]]))return 1;
	return 0;
}
void ser(int x,int y)
{
	if(check(y))return;
	if(y<0)
	{
		for(int i=65;i<=91;i++)
			if(p[i])
				printf("%d ",c[i]);
		return;
	}
	if(x==3)
	{
		int k=c[a[1][y]]+c[a[2][y]]+jin[y];
		int t=0;
		while(k>=n)t++,k-=n;
		jin[y-1]=t;
//		printf("y=%d k=%d jin[%d]=%d\n",y,k,y,jin[y]);
//		jin[y]=0;
		if(!p[a[x][y]]&&!vis[k])
		{
//			printf("%c=%d\n",a[x][y],k);
			c[a[x][y]]=k;
			p[a[x][y]]=1;
			vis[k]=1;
			ser(1,y-1);
			c[a[x][y]]=0;
			p[a[x][y]]=0;
			vis[k]=0;
			return;
		}
		else if(p[a[x][y]]&&vis[k]&&c[a[x][y]]==k)
		{
			ser(1,y-1);
			return;
		}
		else
		{
//			jin[y-1]=0;
			return;
		}
	}
	else if(!p[a[x][y]])
	{
		for(int i=0;i<n;i++)
		{
			if(!vis[i])
			{
//				printf("x=%d y=%d a=%c i=%d\n",x,y,a[x][y],i);
				c[a[x][y]]=i;
				p[a[x][y]]=1;
				vis[i]=1;
				ser(x+1,y);
				c[a[x][y]]=0;
				p[a[x][y]]=0;
				vis[i]=0;
			}
		}
	}
	else ser(x+1,y);
}
int main()
{
	scanf("%d ",&n);
	cin>>a[1];
	cin>>a[2];
	cin>>a[3];
	ser(1,n-1);
	return 0;
}
/*
20 NLHFIEASBRQJOGKMDPCT

NQGPSIIGKDMFDCBFMQSO

PNKNTOLHEIJHFGJKHJGG
*/

  

原文地址:https://www.cnblogs.com/Zinn/p/8474685.html

时间: 2024-10-08 00:58:08

洛谷P1092虫食算——深搜的相关文章

洛谷 P1092 虫食算

P1092 虫食算 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/25448822/ 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,

洛谷 P1092 虫食算 Label:dfs

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

[NOIP2004] 提高组 洛谷P1092 虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

洛谷—— P1092 虫食算

https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/25448822/ 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前

Luogu P1092 虫食算(枚举+剪枝)

P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 44445509678 其中 \(\#\) 号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是 \(5\) 和 \(3\) ,第二行的数字是 \(5\) . 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是 \(N\) 进制加法,算式中三个数都有 \(N\

Luogu P1092 虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

洛谷 P1019 单词接龙 深搜

题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙"中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每

LUGOU P1092 虫食算

传送门 解题思路 刚开始按yzy神犇给的方法写,就是每次要把能算出来的都算出来,结果因为太菜写挂了..后来直接爆搜水过.. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; const int MAXN=40; int n,a[MAXN],cnt; char s[4][MAXN];

P1092 虫食算

题目传送:https://www.luogu.org/problem/show?pid=1092 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #define maxn 30 int n,flag[maxn]; char s[4][maxn]; bool use[maxn]; int id(char ch)/