虫食算

题目链接

似乎可以按位确定每个字母,然后你就得到了一道码农题

所以我们爆搜每个字母的值,然后判断是否合法

朴素的40pts做法

#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100];
string s[10];
void dfs(int x)
{
	if(x==n)
	{
		int xx=0;
		for(int i=n-1;i>=0;i--)
		{
			if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
			xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
		}
		if(xx==0) f=1;
		return;
	}
	for(int i=0;i<n;i++)
	{
		if(!vis[i]) 
		{
			num[x]=i,vis[i]=1;
			dfs(x+1);
			if(f==1) return;
			vis[i]=0;
		}
	}
	
}
int main()
{
	cin>>n;
	for(int i=1;i<=3;i++) cin>>s[i];
	dfs(0);
	for(int i=0;i<n;i++) cout<<num[i]<<" ";
	return 0;
}

在此基础上考虑剪枝

#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100],in[100],line[100],lc=0;
string s[10];
void dfs(int x)
{
	if(in[s[1][0]-'A']<x&&in[s[2][0]-'A']<x&&num[s[1][0]-'A']+num[s[2][0]-'A']>=n) return;//如果最高位上有进位,return
	for(int i=0;i<n;i++)
	{
		if(in[s[1][i]-'A']>=x||in[s[2][i]-'A']>=x||in[s[3][i]-'A']>=x) continue;
		int sum=num[s[1][i]-'A']+num[s[2][i]-'A'];
		if((sum+1)%n!=num[s[3][i]-'A']&&sum%n!=num[s[3][i]-'A']) return;
	}//扫一遍目前已经确定的是不是合法
	if(x==n+1)
	{
		int xx=0;
		for(int i=n-1;i>=0;i--)
		{
			if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
			xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
		}
		if(xx==0) f=1;
		return;
	}
	for(int i=0;i<n;i++)
	{
		if(!vis[i]) 
		{
			num[line[x]]=i,vis[i]=1;
			dfs(x+1);
			if(f==1) return;
			vis[i]=0;
		}
	}
	
}
int main()
{
	cin>>n;
	for(int i=1;i<=3;i++) cin>>s[i];
	
	for(int i=n-1;i>=0;i--)
	for(int j=1;j<=3;j++)
	{
		if(!in[s[j][i]-'A']) //更改确定字母的顺序,按照出现顺序搜索,可以尽早确定同一位上的数字并进行剪枝
		{
			line[++lc]=s[j][i]-'A';
			in[s[j][i]-'A']=lc;
		}
	}
	dfs(1);
	for(int i=0;i<n;i++) cout<<num[i]<<" ";
	return 0;
}

加了好多剪枝~然而还是tle

#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100],in[100],line[100],lc=0;
string s[10];
void dfs(int x)
{
	if(in[s[1][0]-'A']<x&&in[s[2][0]-'A']<x&&num[s[1][0]-'A']+num[s[2][0]-'A']>=n) return;
	for(int i=0;i<n;i++)
	{
		if(in[s[1][i]-'A']>=x||in[s[2][i]-'A']>=x||in[s[3][i]-'A']>=x) continue;
		int sum=num[s[1][i]-'A']+num[s[2][i]-'A'];
		if((sum+1)%n!=num[s[3][i]-'A']&&sum%n!=num[s[3][i]-'A']) return;
	}
	if(x==n+1)
	{
		int xx=0;
		for(int i=n-1;i>=0;i--)
		{
			if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
			xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
		}
		if(xx==0) f=1;
		return;
	}
	for(int i=n-1;i>=0;i--)//将数字的枚举顺序改为倒序
	{
		if(!vis[i]) 
		{
			num[line[x]]=i,vis[i]=1;
			dfs(x+1);
			if(f==1) return;
			vis[i]=0;
		}
	}
	
}
int main()
{
	cin>>n;
	for(int i=1;i<=3;i++) cin>>s[i];
	for(int i=n-1;i>=0;i--)
	for(int j=1;j<=3;j++)
	{
		if(!in[s[j][i]-'A']) 
		{
			line[++lc]=s[j][i]-'A';
			in[s[j][i]-'A']=lc;
		}
	}
	dfs(1);
	for(int i=0;i<n;i++) cout<<num[i]<<" ";
	return 0;
}

然后就玄学ac了qwq

posted @ 2020-09-10 16:22  zlq,  阅读(274)  评论(0编辑  收藏  举报