《ybtoj高效进阶》第一部分第四章例题3 虫食算&P1092

题目大意

给一组n进制加法竖式,位数必为n,可以有前导零,每个字母对应一个不同的数字,求一组解。保证有解且唯一。

思路

我们显然只能用dfs解决该题目,所以需要剪枝
剪枝1:我们模拟手动计算,如果在当前情况下已经无解马上回溯
剪枝2:因为解有且唯一,我们一旦找到解就马上输出并结束程序
code:

#include<cstdio>
#include<queue>
#include<iostream>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
int n,tot,no[27];
bool ow,vis[27],us[27];
char o[3][27],cr[27];
bool check()
{
 int x=0;
 for (int i=n-1;i>=0;i--)
 {
  int add1=no[o[0][i]-'A'],add2=no[o[1][i]-'A'],he=no[o[2][i]-'A'];
  if (add1!=-1&&add2!=-1&&he!=-1)
  {
   if (x==-1)
   {
    if ((add1+add2)%n!=he&&(add1+add2+1)%n!=he)
    {
     return 0;
    }
    if (i==0&&add1+add2>=n)
    {
     return 0;
    }
   }
   else
   {
    if ((add1+add2+x)%n!=he)
    {
     return 0;
    }
    if ((add1+add2+x)>=n&&i==0)
    {
     return 0;
    }
    x=(add1+add2+x)/n;
   }
  }
  else x=-1;
 }
 return 1;
}
bool dfs(int x)
{
 if (x==tot)
 {
  return 1;
 }
 for (int i=0;i<n;i++)
 {
  if (us[i]==0)
  {
   us[i]=1;
   no[cr[x]-'A']=i;
   if (check()&&dfs(x+1)) return 1;
   us[i]=0;
  }
 }
 no[cr[x]-'A']=-1;
 return 0;
}
int main()
{
 memset(no,-1,sizeof(no));
 scanf("%d",&n);
 for (int i=0;i<3;i++)
 {
  scanf("%s",o[i]);
 }
 for (int i=n-1;i>=0;i--) for (int j=0;j<3;j++)
 {
  if (vis[o[j][i]-'A']==0)
  {
   vis[o[j][i]-'A']=1;
   cr[tot++]=o[j][i];
  }
 }
 dfs(0);
 for (int i=0;i<n;i++) printf("%d ",no[i]);
 return 0;
}

致盯着ybtoj系列的OIer:有些ybtoj的题目缺失,是因为之前已经做过重题的题解,就不再补发了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值