题目传送

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

  对于一道搜索题,首先考虑一下大体怎样搜索。因为要考虑加法的进位,所以从左往右搜索对于考虑进位来说十分麻烦,而从右往左搜索就没有这种麻烦,故搜索顺序从右往左。但是发现整个式子的一位上由三个字符串的一位组成,且这三个分别担当加数、结果中的一部分,逐个搜索的话还要麻烦地分类讨论,考虑再优化一下搜索顺序。发现一共只有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. 【Qt开发】Qt让线程休息一段时间

    Qt 为何没有提供 Sleep 论坛上不时见到有人问: Qt 为什么没有提供跨平台的 sleep 函数? 使用平台相关的 Sleep 或 nanosleep 以后,界面为什么没有反应? QThread ...

  2. react-native的技巧

    按钮定制 給图片添加点击事件 <TouchableOpacity onPress={this.lookAlbum} style={{flex: 0, height: 40, width: 40, ...

  3. Simplify Path(路径简化)

    问题: 来源:https://leetcode.com/problems/simplify-path Given an absolute path for a file (Unix-style), s ...

  4. [Git] 020 stash —— Git 中的”皮姆粒子“

    0. 我准备模拟两种情况 第一种 第二种 情况简析 仓库中的最新版本发现 Bug,需要立即修复 当前在 "dev" 分支中工作到一定程度,尚不能提交,但删之可惜 ps: 在分支中没 ...

  5. Skiing POJ 3037 很奇怪的最短路问题

    Skiing POJ 3037 很奇怪的最短路问题 题意 题意:你在一个R*C网格的左上角,现在问你从左上角走到右下角需要的最少时间.其中网格中的任意两点的时间花费可以计算出来. 解题思路 这个需要发 ...

  6. 从汇编到C

    一. 设置栈 1.1. C语言运行时需要和栈的意义 1.1.1. “C语言运行时(runtime)”需要一定的条件,这些条件由汇编来提供.C语言运行时主要是需要栈 1.1.2. C语言与栈的关系 a. ...

  7. 关于微信H5页面开发中音乐不自动播放的解决方法

    我想应该有很多人在做H5场景应用.H5微刊.H5微杂志的时候加入背景音乐吧(客户需求),相信很多人一定碰过不能自动播放的时候,即使是相同的iPhone 5s也有不播放的时候,很蛋疼吧!? 之前我的解决 ...

  8. 实例学习——爬取豆瓣网TOP250数据

    开发环境:(Windows)eclipse+pydev 网址:https://book.douban.com/top250?start=0 from lxml import etree #解析提取数据 ...

  9. 洛谷 - P1462 - 通往奥格瑞玛的道路 - 二分 - Dijkstra

    https://www.luogu.org/problem/P1462 感觉,要二分最大收费权的城市,把小于等于它的全部插进去,Dijkstra一下求出最小的血量.这样感觉太暴力了. 考虑只有1000 ...

  10. luogu P5338 [TJOI2019]甲苯先生的滚榜

    传送门 首先,排名系统,一看就知道是原题,可以上平衡树来维护 然后考虑一种比较朴素的想法,因为我们要知道排名在一个人前面的人数,也就是AC数比他多的人数+AC数一样并且罚时少的人数,所以考虑维护那两个 ...