这个式子是是由\(A\sim A+N\)组成的,那么\(A\sim A+N\)就只能等于\(0\sim N-1\),因此我们每次对\(A\sim A+N\)的取值做一个新的排列,然后judge一下当前状态是否可行,若可行直接输出解。

显然\(N!\)过于庞大,需要剪枝。

剪枝:

假设一个这种情况:

XXXAXXX
XXXBXXX
XXXCXXX

其一,在一个排列中设\(A+B=k\),\(A+B<C\)时,在其它任意一个排列中,若\(A+B<k\),那么这个排列肯定不合法,\(A+B<C+N\)同理。

其二,在一排里,进位至多为1,那么仅\((A+B)\%N=C\)和\((A+B+1)\%N=C\)这两种情况成立。有了这个优化我们就不需要一了。

其三,由于三排长度都是\(N\),意味着最高位没有进位。

其四,在二的判断中,倘若我们能够早一些找到不合法的情况,那么这个题就可以得到更好的优化。显然,在检验二时,我们是从某一边的最边上那一排开始扫到末尾那一排,所有如果我们搜索时先搜出早一点扫到的那部分字母对应的数字,就会减少大量无用枝条。

复杂度\(O(EIS)\)

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 101
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,num[N],q[N],cnt;
char mp[4][N];
bool v[N],use[N];
inline void judge()
{
int add=0;
for(int i=n;i>=1;--i){
if((num[mp[1][i]]+num[mp[2][i]]+add)%n==num[mp[3][i]])
add=(num[mp[1][i]]+num[mp[2][i]]+add)/n;
else return;
}
for(int i='A';i<'A'+n;++i)
printf("%d ",num[i]);
exit(0);
}
inline bool can()
{
for(int i=n;i>=1;--i){
if(num[mp[1][i]]==-1||num[mp[2][i]]==-1||num[mp[3][i]]==-1) continue;
if((num[mp[1][i]]+num[mp[2][i]])%n!=num[mp[3][i]])
if((num[mp[1][i]]+num[mp[2][i]]+1)%n!=num[mp[3][i]])
return 0;
}
return 1;
}
inline void dfs(int now)
{
if(now>n){
judge();return;
}
for(int i=n-1;i>=0;--i){
if(use[i]) continue;
num[q[now]+'A']=i;
if(can()){
use[i]=1;
dfs(now+1);
use[i]=0;
}
}
num[q[now]+'A']=-1;
}
int main()
{
n=read();
memset(num,-1,sizeof(num));
for(int i=1;i<=3;++i) scanf("%s",mp[i]+1);
for(int i=n;i>=1;--i){
if(!v[mp[1][i]-'A']) q[++cnt]=mp[1][i]-'A',v[mp[1][i]-'A']=1;
if(!v[mp[2][i]-'A']) q[++cnt]=mp[2][i]-'A',v[mp[2][i]-'A']=1;
if(!v[mp[3][i]-'A']) q[++cnt]=mp[3][i]-'A',v[mp[3][i]-'A']=1;
}
dfs(1);
return 0;
}

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$虫食算

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

  6. 洛谷 P1092 虫食算 Label:dfs

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

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

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

  8. P1092 虫食算(洛谷)

    今天做了一道题,我之前吹牛的时候曾经说:“这个题我觉得深搜剪枝一下就可以了.”. 我觉得我之前说的没错“这个题深搜剪枝亿下,再加点玄学就可以了!” 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子 ...

  9. Luogu P1092 虫食算

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

随机推荐

  1. 2019年上海市大学生网络安全大赛两道misc WriteUp

    2019年全国大学生网络安全邀请赛暨第五届上海市大学生网络安全大赛 做出了两道Misc== 签到 题干 解题过程 题干提示一直注册成功,如果注册失败也许会出现flag. 下载下来是包含010edito ...

  2. Cut 命令截取不同空格的string

    eth0      Link encap:Ethernet  HWaddr 00:0C:29:16:79:98 例如这一串中间空格数量不一样cut 是无法截取字段的.所以我们需要把他变成有规律的. 这 ...

  3. ASP.NET Core WebApi基于Redis实现Token接口安全认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebSer ...

  4. thinkphp验证码不现实多半是bom惹的祸

    thinkphp 验证码不现实多半是bom惹的祸,下面是驱除bom的代码: 链接:https://pan.baidu.com/s/1v5gm7n0L7TGyejCmQrMh2g 提取码:x2p5 免费 ...

  5. Java学习:Lambda表达式

    Lambda表达式 函数式编程思想概述---强调做什么,而不是以什么形式做 面向对象的思想: 做一件事情,找一个能解决这个的事情的对象,调用对象的方法,完成事情 函数式编程思想 只要能获取到结果,谁去 ...

  6. SpringCloud面试题及答案

    1. 什么是 spring cloud? spring cloud 是一系列框架的有序集合.它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心. ...

  7. java中static和final修饰符

    static和final修饰符 一.static修饰符 static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. ...

  8. EntityFramework执行Add-Miragtion或者Update-Database出闲ScriptHalted

    今天基友在他本机运行我的项目,执行ef还原数据的时候,一直出现ScriptHalted的错误. 找了下百度,只找到一个stackoverflowd的答案,没有看到中文的解决方案. 现在总结一下,并给出 ...

  9. 用C#搭建WebSocket

    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 W ...

  10. j.u.c: Java并发包的5大块

    //TODO Executors: ExecutorService executor = Executors.newFixedThreadPool(10);... newForkJoinPool(). ...