今天做了一道题,我之前吹牛的时候曾经说:“这个题我觉得深搜剪枝一下就可以了。”。

我觉得我之前说的没错“这个题深搜剪枝亿下,再加点玄学就可以了!”

题目描述
所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子: 43#9865#045
+ 8468#6633
44445509678
其中 # 号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是 5 和 3,第二行的数字是 5。 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算。这里的加法是 n 进制加法,算式中三个数都有 n 位,允许有前导的 0。 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是 n 进制的,我们就取英文字母表的前 n 个大写字母来表示这个算式中的 0 到 n - 1 这 n 个不同的数字:但是这 n 个字母并不一定顺序地代表 0 到 n−1。输入数据保证 n 个字母分别至少出现一次。 BADC
+CBDA
DCCC
上面的算式是一个4进制的算式。很显然,我们只要让 ABCD 分别代表 0123,便可以让这个式子成立了。你的任务是,对于给定的 n 进制加法算式,求出 n 个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解。 输入格式
输入的第一行是一个整数 n,代表进制数。 第二到第四行,每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这 3 个字符串左右两端都没有空格,从左到右依次代表从高位到低位,并且恰好有 n 位。 输出格式
输出一行 n 个用空格隔开的整数,分别代表 A,B,… 代表的数字。 输入输出样例
输入 #1复制
5
ABCED
BDACE
EBBAA
输出 #1复制
1 0 3 4 2
说明/提示
数据规模与约定
对于 30% 的数据,保证 n≤10;
对于 50% 的数据,保证 n≤15;
对于 100% 的数据,保证 1≤n≤26。

  

惨烈的提交记录(20分开始是用深搜剪枝+玄学,20分之前是吹牛时打的模拟)

开始讲思路了,首先,我们看看是如何排除纯洁的搜索的,这个题n最大是26,不剪枝的效率是O(n!)。时限一秒。虽然我不知道一秒准确的运行次数,但我知道肯定不够。这时候就要剪枝了。先说第一个思路,如果一个算式是1+1=3,我们可以一眼看出他是错的,但如果是在十位,百位,就不一定了,因为前面的位可能会进位。但如果是1+1=4,那说什么都不可能了,所以我们的第一个思路就是,如果这一位的2个数相加不等于结果,而且这一位的2个数相加再+1还是不等于结果,这就说明你有数是选错的,退出吧。

虽然这个剪枝很好想,但是他帮我们优化了很多,不过,这不够,我们需要继续优化(不然就50分吧,20是因为脑残,逻辑搞错了)。所以请出第二个优化,众所周知这是一个n位数,也就是说,前两个数的最高位是不进位的。证明这个小学生都会……

所以第二个优化就是,如果现在的情况让a和b的最高位进位了,那就可以放弃了,因为c就不是n位数了。

然后是第三个优化,2个应该是不够的,再来一个。我们从第一个优化可以得知,剪枝条件是某一位的2个数加起来不可能得到结果,就剪枝,所以我们先求同一位的3个字母,就可以很早的去掉一些枝枝杈杈,而且这些枝杈特别大,也是一个很有用的优化。

我们加了这么多优化,应该可以了吧,但是!他TLE了,60分。合着我加了这么多优化你就多给我10分(强忍心中怒火)。所以我们还是要继续优化(需要亿点点优化)

emm,我们再来看一遍题目,会发现一个奇妙的地方,”每个字母分别代表一个数“。这说明什么?这说明不会有2个字母的数字一样,再换种说法,一个数字被别的字母用了,这个字母就不能用了。我们就可以发现一个好像优化一点的算法。我们可以在判断的地方加一个处理,如果c的这一位减去有数的一位,但是剩下的那个数无论如何都被用了,那就是不可能的一种。剪枝吧。

虽然看着很强的样子,但是仍然60。什么鬼!

而且把我整的有点乱,我就删掉了他,开始颓废了,我改了改搜索的先后顺序,哎?我下载的数据过了?

蛤?我决定碰碰运气,提交上去,哦豁!80分。

仍然没过……,但我突然觉得我写的有些繁琐,而且明明可以不用map,我用了。我就把map改成了普通数组,然后,过了?!

事后,我去测试了一下2个代码的运行速度,map比正常数组慢好多,所以能用普通数组就别瞎用map。

嗯,说的差不多了,放代码吧(臭长臭长的代码)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
long long n,e,ok;
long long sz[30];
long long mp[30];
long long bj[30];
string a,b,c;
long long ea,eb,ec;
void zpd()//这个是最后的判断
{
int bl=0;//bl是进位了多少
for(int i=n-1;i>=0;i--)
{
if((mp[a[i]]+mp[b[i]]+bl)%n!=mp[c[i]])//正经的操作,有一种高精的感觉。一旦不合理就退出。
{
return;
}
bl=(mp[a[i]]+mp[b[i]]+bl)/n;//算出下一次的bl。
}
for(int i=0;i<n;i++)
{
cout<<mp[i]<<" ";//没有错误,这是对的,输出他
}
exit(0);//停止一切,完结撒花。
}
int pd()//最大的优化
{
if(mp[a[0]]+mp[b[0]]>=n)//第二个优化,看起来不起眼,他帮我多得了10分呢。
{
return 2;
}
for(int i=n-1;i>=0;i--)//又是玄学的倒序搜索
{
ea=mp[a[i]];//先存下来快一点(应该)(为了时间少点啥奇怪的东西都试了一遍)
eb=mp[b[i]];
ec=mp[c[i]];
if(ea==-1||eb==-1||ec==-1)//这一位算不出来,跳过。
{
continue;
}
if((ea+eb)%n!=ec&&(ea+eb+1)%n!=ec)//这一位可以算出来,看看合理不,不合理就踢出去
{
return 2;
}
}
return 1;//没被踢出去,目前来说是可行的,继续吧。
}
void dfs(int wz)
{
if(pd()==2)//最有用的优化
{
return;
}
if(wz==n)//长度到了,最后的审判。
{
zpd();
}
for(int i=n-1;i>=0;i--)//玄学倒序搜索
{
if(bj[i]==0)
{
bj[i]=1;//这个数被用过
mp[sz[wz]]=i;//sz数组是每个字母出现的先后顺序,也是一个优化,mp是记录值用的。
dfs(wz+1);
bj[i]=0;
mp[sz[wz]]=-1;
}
}
}
void msy(int c)//这玩意写在main函数里我看着不爽,就放这里来了(我不想让他太长)
{
if(bj[c]==0)
{
bj[c]=1;
sz[ok]=c;//储存字母出现的顺序
ok++;
}
}
int main()
{
scanf("%lld",&n);//一开始我没写(陋习)挣扎着试图减少点时间。
cin>>a>>b>>c;
for(int i=0;i<n;i++)
{
a[i]=a[i]-'A';//不用map!
b[i]=b[i]-'A';//不用map!
c[i]=c[i]-'A';//不用map!重要的事情说3遍
}
for(int i=0;i<n;i++)
{
mp[a[i]]=-1;
mp[b[i]]=-1;
mp[c[i]]=-1;
}
for(int i=0;i<n;i++)
{
bj[a[i]]=0;
bj[b[i]]=0;
bj[c[i]]=0;
}
for(int i=n-1;i>=0;i--)//第三个优化,先搜索某一位所有字母
{
msy(a[i]);
msy(b[i]);
msy(c[i]);
}
for(int i=0;i<n;i++)//还是初始化
{
bj[a[i]]=0;
bj[b[i]]=0;
bj[c[i]]=0;
}
dfs(0);
return 0;
}

写这玩意让我又学到了一些东西,比如可以用一般数组就别瞎用map,又比如玄学真强。

好了就这样吧,希望大家听懂了。

P1092 虫食算(洛谷)的更多相关文章

  1. 洛谷P1092 虫食算

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

  2. 【题解】 P1092虫食算

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

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

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

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

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

  5. 洛谷 P1092 虫食算 Label:dfs

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

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

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

  7. 洛谷—— P1092 虫食算

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

  8. Luogu P1092 虫食算

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

  9. 【搜索】$P1092$虫食算

    题目链接 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同 ...

随机推荐

  1. 详说tcp粘包和半包

    tcp服务端和客户端建立连接后会长时间维持这个连接,用于互相传递数据,tcp是以流的方式传输数据的,就像一个水管里的水一样,从一头不断的流向另一头. 理想情况下,发送的数据包都是独立的, 现实要复杂一 ...

  2. Apollo配置中心的实战

    31.携程 Apollo 配置中心介绍~1.mp4 32.Apollo核心概念~1.mp4 32.Apollo核心概念~1.mp4 每个应用需要有一个唯一的AppID 要在指定的机器上的server. ...

  3. Python-argparse模块-获取命令行参数

    #!/usr/bin/python3 """ Author : Jet Bi License : www.cyeap.com Summary : 获取命令行的参数 Not ...

  4. 分享 HT 实用技巧:实现指南针和 3D 魔方导航

    前言 三维场景时常需要一个导航标识,用来确定场景所处的方位. 一般有两种表现形式:指南针.小方盒(方位魔方). 参考一下百度百科中的 maya 界面,可以看到右上角有一个标识方位的小盒子,说的就是它: ...

  5. ABP(ASP.NET Boilerplate Project)快速入门

    前言 这两天看了一下ABP,做个简单的学习记录.记录主要有以下内容: 从官网创建并下载项目(.net core 3.x + vue) 项目在本地成功运行 新增实体并映射到数据库 完成对新增实体的基本增 ...

  6. JS代码简洁之道--函数

    函数的参数越少越好 有一个准则是:如果你的函数参数超过两个,就应该改为对象传入. 这样做是合理的,因为当函数参数超过两个时,参数顺序开始变得难以记忆,而且容易出现一种很尴尬的情况:比如我只需要传入第三 ...

  7. Docker(六)容器数据卷

    容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像 需求:数据可以持久化和同步 使用数据卷 指定路径挂载 docker run -it -v 主机目录:容器内目录 # 测试 [root@h ...

  8. spark | 手把手教你用spark进行数据预处理

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是spark专题的第七篇文章,我们一起看看spark的数据分析和处理. 过滤去重 在机器学习和数据分析当中,对于数据的了解和熟悉都是最基 ...

  9. Java基础Day08(多线程)

    多线程 1. 线程 1.1 什么是线程: 程序中负责执行的哪个东东就叫做线程(执行路线,进程内部的执行序列或者说是进程的子任务) 多线程执行时,在栈内存中,每一个执行线程都有自己所属的栈内存空间.进行 ...

  10. 阿里云Linux CentOS8.1 64位服务器安装LNMP(Linux+Nginx+MySQL+PHP)

    LNMP环境和软件版本: 名称 版本号 查询命令 Linux系统 CentOS Linux release 8.1.1911 (Core) cat /etc/redhat-release Nginx ...