YbtOJ 深度搜索课堂过关 例3 虫食算【深度优先搜索】【优化】

在这里插入图片描述


思路

这道题我们首先把输入的字母按出现顺序放到一个数组里。
这样如果直接暴力的话会超时,所以考虑要优化。
如果当前有值没有被枚举过,我们就可以设一个标记为 − 1 -1 1
我们肯定从低位到高位算,

如果在设为 − 1 -1 1 之后又有一位上三个值都被枚举过了的话,
那么我们就分成是否被进位讨论,
没有进位,那么 a + b a+b a+b 的个位就要等于 c c c
有进位,那么 a + b + 1 a+b+1 a+b+1 的个位就要等于c,

如果前面所有位的值都被枚举过了,
那我们就可以直接进行加法进位,

如果两个条件都不满足,则失败,直接返回即可。

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int en[75],bj[27],num[27];
string s[3];
char a[27];
int n,c,w;
bool check()
{
    
    
	int jw=0,t=0; 
	for(int i=s[0].size()-1; i>=0; i--)
     {
    
    
     	int a=num[s[0][i]-64];
     	int b=num[s[1][i]-64];
     	int c=num[s[2][i]-64];
     	if(a==-1||b==-1||c==-1)
     	 {
    
    
		   t=-1;
     	   continue;
		 }
     	if(t==-1)
     	 {
    
    
     	 	if((a+b)%n!=c&&(a+b+1)%n!=c)
     	 	  return 0;
     	 	if(((a+b)/n>0||(a+b+1)/n>0)&&i==0)
     	 	  return 0;
		 }
		else
		 {
    
    
		 	if((a+b+jw)%n!=c)
		 	  return 0;
		 	jw=(a+b+jw)/n;
		 	if(jw>0&&i==0)
     	 	  return 0;
		 }
	 }
	return 1;
}
void dfs(int wx)
{
    
    
	//cout<<wx<<endl;
	if(w==1)
	  return;
	if(wx>n)
	 {
    
    
	 	for(int i=1; i<=n; i++)
	 	   cout<<num[i]<<" ";
	 	w=1;
	    return;
	 }
	for(int i=0; i<n; i++)
	 {
    
    
	 	if(bj[i]==0)
	 	 {
    
    
	 	 	num[a[wx]-64]=i;
	 	 	bj[i]=1;
	 	 	if(check())
	 	 	  dfs(wx+1);
	 	 	num[a[wx]-64]=-1;
	 	 	bj[i]=0;
	     }
	 }
}
int main()
{
    
    
	memset(num,-1,sizeof(num));
	cin>>n;
	cin>>s[0]>>s[1]>>s[2];
	for(int i=s[0].size()-1; i>=0; i--)
	 for(int j=0; j<=2; j++)
	  {
    
    
	  	if(en[s[j][i]-64]==0)
	  	 {
    
    
            a[++c]=s[j][i];
			en[s[j][i]-64]=1;
		 }
	  }
	dfs(1);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/112383508