ICPC Pacific Northwest Regional Contest 2019 L. Carry Cam Failure 分析加搜索

一个不进位的乘法。

相当于每一位乘a后移项进行不进位的加法。

比如:

1234[*]99

由于9[*]1234=9876

则:摆出计算式:

  9876

9876

————

975436

即:a[*]b=c

c的第i位等于:

其中a_0b_k表示a_0[*]b_k,比如3[*]4=2

我们可以先打一个不进位乘法表方便处理。

然后进行搜索。

发现x[*]x,得到的N的位数为x的位数*[x的位数-1]

即x最多13位。

且我们一位一位的处理,发现每一位只与当前位之前的位数有关。

且当前位满足  k[*]x[+] q= z。  其中k,q,z是常量,  z即当前位对应的结果。//具体看代码

发现满足x的d不会太多。

具体最大为2.//我不太会证,但我知道肯定很小

2^ {13} 的复杂度完全可以接受。

由于要输出最小,我们从高位往低位dfs。输出第一个搜到的答案即可。

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;}
*/
int n,L;
bool f;
int mp[10][10];//新的乘法表 
char s[100];
int p[100];
int a[100];
void dfs(int x)
{
	if(f)return ;
	if(x==L+1)
	{
		f=true;
		//输出结果 
		for(int i=1;i<=n;i++)cout<n&&d)return;
		for(int j=1;j<=x;j++)
		{
			if(x-j+1>n)continue;
			tp+=mp[a[j]][a[x-j+1]];
			tp%=10;
		}
		if(tp==p[x])dfs(x+1);
	}
}
int main()
{
  	for(int i=0;i<=9;i++)
  		for(int j=i;j<=9;j++)
  			mp[i][j]=mp[j][i]=i*j%10;
	cin>>s;
	L=strlen(s);
	n=(L+1)/2;
	for(int i=1;i<=L;i++)p[i]=s[i-1]-'0';
	dfs(1);//取到第几位 
	if(!f)cout<<-1<

 

你可能感兴趣的:(搜索,网络赛)