题目传送

(据说官方正解为高斯消元,但用搜索也能过,这里就讲讲搜索算法吧。)

  对于一道搜索题,首先考虑一下大体怎样搜索。因为要考虑加法的进位,所以从左往右搜索对于考虑进位来说十分麻烦,而从右往左搜索就没有这种麻烦,故搜索顺序从右往左。但是发现整个式子的一位上由三个字符串的一位组成,且这三个分别担当加数、结果中的一部分,逐个搜索的话还要麻烦地分类讨论,考虑再优化一下搜索顺序。发现一共只有n个不同的数和字母,并且每个数和字母都至少出现一次,那么可以从右往左找出字母第一次出现的位置并存到next数组里,只要按照next数组搜一遍就完事了。

  显然一个裸搜在此题肯定会TLE了,考虑一下剪枝。由于每个字符串都有n位,那么作为加数的两个字符串的最高位加进位加起来一定不能大于等于n导致进位。同时如果发现在同一位的数若都已经确定,发现两加数那一位上的数的和mod n(不进位的情况)不等于结果那一位上的数,并且两加数那一位上的数的和+1再mod n(进位的情况)仍然不等于结果那一位上的数,显然是不合题意的,故要剪掉。

  一个小技巧:发现相同的字母代表相同的数。我们可以把字母数字化,即每个字母都减'A'加1,这样若原字母为'A',处理后就为1,若为'B',就为2,...以此类推。这样可以让处理后的值作为最后记录答案的数组num的下标,同一个字母处理后的变为的下标也一样,故可以统一处理。

见AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib> using namespace std; int n; char s1[],s2[],s3[]; int a[],b[],c[],next[],cnt,num[]; bool used[]; inline void getused(int x)//处理出next数组
{
if(!used[x])
{
used[x]=;
next[++cnt]=x;
}
} inline int canprune()//剪枝判断 prune:剪枝(来自翻译)
{
if(num[a[]]+num[b[]]>=n)
return ;
int A,B,C;
for(int i=n;i>=;i--)
{
A=num[a[i]],B=num[b[i]],C=num[c[i]];
if(A==-||B==-||C==-) continue;
if((A+B)%n!=C&&(A+B+)%n!=C) return ;
}
return ;
} inline int judge()//结果判断
{
if(num[a[]]+num[b[]]>=n)
return ;
int A,B,C,x=;
for(int i=n;i>=;i--)
{
A=num[a[i]],B=num[b[i]],C=num[c[i]];
if((A+B+x)%n!=C) return ;
x=(A+B+x)/n;
}
return ;
} void print()
{
for(int i=;i<n;i++)
printf("%d ",num[i]);
cout<<num[n];
exit();//要用 stdlib.h 或 cstdlib库(少了头文件的话本地虽然能过,但交上去就回CE),作用是直接退出程序。
} void dfs(int k)
{
for(int i=n-;i>=;--i)
if(!used[i])
{
num[next[k]]=i;
used[i]=;
if(k==n)
{
if(judge())
print();
}
else
{
if(!canprune())
dfs(k+);
}
num[next[k]]=-;
used[i]=;
}
} int main()
{
scanf("%d",&n);
scanf("%s%s%s",s1,s2,s3);
for(int i=n;i>=;--i)
{
a[i]=s1[i-]-'A'+;
getused(a[i]);
b[i]=s2[i-]-'A'+;
getused(b[i]);
c[i]=s3[i-]-'A'+;
getused(c[i]);
}
memset(num,-,sizeof num);
memset(used,,sizeof used);
dfs();
return ;
}

P1092 虫食算——题解的更多相关文章

  1. P1092 虫食算 题解(搜索)

    题目链接 P1092 虫食算 解题思路 好题啊!这个搜索好难写...... 大概是要考虑进位和考虑使用过某个数字这两个东西,但就很容易出错...... 首先这个从后往前搜比较好想,按照从后往前出现的顺 ...

  2. 【题解】 P1092虫食算

    [题解]P1092 虫食算 老题了,很经典. 用到了一些搜索套路. 可行性剪枝,劣者靠后,随机化,\(etc......\) 搜索设参也很有技巧,设一个\(adjustment\)参数可以很方便地在两 ...

  3. 洛谷P1092 虫食算

    P1092 虫食算 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/2544 ...

  4. Luogu P1092 虫食算(枚举+剪枝)

    P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...

  5. 洛谷 P1092 虫食算 Label:dfs

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  6. Luogu P1092 虫食算

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  7. [NOIP2004] 提高组 洛谷P1092 虫食算

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  8. 洛谷—— P1092 虫食算

    https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简 ...

  9. NOIP 2004 虫食算题解

    问题 E: [Noip2004]虫食算 时间限制: 1 Sec  内存限制: 128 MB 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一 ...

随机推荐

  1. ARP协议基础

    ARP 什么是ARP协议 ARP协议是能够根据IP地址解析出该IP地址所在设备的MAC地址,叫(Address Resolution Protocol)地址解析协议 ARP地址的工作流程 当一台主机A ...

  2. Linux-Spark-Hadoop-Hive安装配置

    1. JAVA安装配置:https://www.cnblogs.com/lamp01/p/8932740.html 2. Spark安装配置:https://www.cnblogs.com/vince ...

  3. 文件压缩、解压工具类。文件压缩格式为zip

    package com.JUtils.file; import java.io.BufferedOutputStream; import java.io.File; import java.io.Fi ...

  4. SpringBoot 使用JPA+MySQL+Thymeleaf 总结 二

    SpringBoot 使用JPA+MySQL+Thymeleaf 总结 一 SpringBoot 使用JPA+MySQL+Thymeleaf 总结 二 方法一 使用原生sql查询 或者 为方法名增加 ...

  5. [2019多校联考(Round 6 T3)]脱单计划 (费用流)

    [2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...

  6. hive中的索引创建

    1.在hive中创建索引所在表 create table if not exists h_odse.hxy(id int,name string,hobby array<string>,a ...

  7. 20170309工作笔记--------如何用好dialog,想变什么样就变成什么样

    (1)首先自定义一个dialog的div,并且写内容 (2)运用相应的代码进行控制,弹出dialog $(".tel").click(function() { $("#d ...

  8. Chrome开发者工具详解(五)之Network面板

    Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板. Timeline面板.Profiles面板.Application面板.Se ...

  9. html中的dl,dt,dd标签

    html <dl> <dt> <dd>是一组合标签,使用了dt dd最外层就必须使用dl包裹,此组合标签我们也又叫表格标签,与table表格类似组合标签,故名我们也 ...

  10. js中封装一个自己的简单数学对象

    封装一个数学对象求最大值最小值 <script> var myMath={ PI:3.1415926, max:function(){ var max=arguments[0];//注意a ...