zoukankan      html  css  js  c++  java
  • 虫食算

    题目链接

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

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

    朴素的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

  • 相关阅读:
    ElasticSearch 基础<转载>
    计算文本相似度方法总结(一)
    Java入门1---关键字、标识符、变量、运算符、流程控制、数组
    IntelliJ IDEA安装
    java代码转python代码
    python2和python3切换
    在markdown中插入github仓库中的图片
    MySQL:管理MySQL、事务(三)
    MySQL:查询、修改(二)
    MySQL:主键、外键、索引(一)
  • 原文地址:https://www.cnblogs.com/qwq-/p/13646472.html
Copyright © 2011-2022 走看看