传送门

Description

Input

包含四行。

第一行有一个正整数 (N≤26)。

后面的三行,每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

Output

一行,即唯一的那组解。

解是这样表示的:输出NN个数字,分别表示A,B,C,…所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

Sample Input

5

ABCED

BDACE

EBBAA

Sample Output

1 0 3 4 2

INIT

对于30%的数据,保证有N≤10;

对于50%的数据,保证有N≤15;

对于全部的数据,保证有N≤26。

noip2004提高组第4题

Solution

暴力搜索剪枝没啥好说的。。。

写完才明白按照一列搜索比按字母搜索要快好多,也好剪枝

于是我写了一大堆特判才卡过

Code

丑陋的代码

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
using namespace std; inline int read() {
int x=0,f=1;char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
} const int N=30;
bool flag;
int n,tot,cnt;
bool vis[N];
int A[N],B[N],C[N],mp[N],sta[N],deg[N],id[N];
char ch[N]; bool ck() {
int A1=mp[A[1]],B1=mp[B[1]],C1=mp[C[1]];
if(~A1&&~C1&&A1>C1) return 0;
if(~B1&&~C1&&B1>C1) return 0;
if(~A1&&~B1) {
if(A1+B1>tot-1) return 0;
if(~C1&&A1+B1!=C1&&A1+B1+1!=C1) return 0;
}
int las=0;
R(i,1,n) {
int CA=A[i],CB=B[i],CC=C[i];
int &DA=mp[A[i]],&DB=mp[B[i]],&DC=mp[C[i]];
if(~DA&&~DB&&~DC) {
if(las==-1&&(DA+DB+1)%tot!=DC&&(DA+DB)%tot!=DC) return 0;
if(~las&&(DA+DB+las)%tot!=DC) return 0;
if(~las) las=(DA+DB+las)/n;
if(las==-1&&DA+DB>=n) las=1;
}
else if(~DA&&~DB) {
if(~las&&vis[(DA+DB+las)%tot]) return 0;
if(las==-1&&vis[(DA+DB)%tot]&&vis[(DA+DB+1)%tot]) return 0;
if(~las&&DC==-1) DC=(DA+DB+las)%tot,vis[DC]=1,sta[++cnt]=CC;
}
else if(~DA&&~DC) {
int dc=DC; if(dc<=DA) dc+=tot;
if(~las&&vis[dc-DA-las]) return 0;
if(las==-1&&vis[dc-DA]&&vis[dc-DA-1]) return 0;
if(~las&&DB==-1) DB=dc-DA-las,vis[DB]=1,sta[++cnt]=CB;
}
else if(~DB&&~DC) {
int dc=DC; if(dc<=DB) dc+=tot;
if(~las&&vis[dc-DB-las]) return 0;
if(las==-1&&vis[dc-DB]&&vis[dc-DB-1]) return 0;
if(~las&&DA==-1) DA=dc-DB-las,vis[DA]=1,sta[++cnt]=CA;
}
if(~DA&&~DB&&~las) las=(DA+DB+las)/n;
if(las==-1&&~DA&&~DB&&DA+DB>=n) las=1;
if(DA==-1||DB==-1||DC==-1) las=-1;
}
return 1;
} void dfs(int pos) {
if(flag) return ;
if(~mp[id[pos]]) {dfs(pos+1);return ;}
if(pos==tot+1) {
F(i,1,tot) printf("%d ",mp[i]);
flag=1; return ;
}
F(i,0,tot-1) if(!vis[i]) {
mp[id[pos]]=i; vis[i]=1; int ls=cnt;
if(ck()) dfs(pos+1);
mp[id[pos]]=-1; vis[i]=0;
while(cnt>ls) vis[mp[sta[cnt]]]=0,mp[sta[cnt]]=-1,cnt--;
if(flag) return ;
}
} bool cmp(int x,int y) {return deg[x]>deg[y];} int main() {
n=read();
scanf("%s",ch+1);F(i,1,n) {A[i]=ch[i]-'A'+1;if(!vis[A[i]]) tot++,vis[A[i]]=1;deg[A[i]]++;}
scanf("%s",ch+1);F(i,1,n) {B[i]=ch[i]-'A'+1;if(!vis[B[i]]) tot++,vis[B[i]]=1;deg[A[i]]++;}
scanf("%s",ch+1);F(i,1,n) {C[i]=ch[i]-'A'+1;if(!vis[C[i]]) tot++,vis[C[i]]=1;deg[A[i]]++;}
memset(mp,-1,sizeof(mp)); memset(vis,0,sizeof(vis));
F(i,1,n) id[i]=i;
sort(id+1,id+1+n,cmp);
F(i,1,n) if(A[i]==B[i]&&B[i]==C[i]) {mp[A[i]]=0;vis[0]=1;dfs(1);return 0;}
F(i,1,n) if((A[i]==C[i])&&A[i]!=B[i]) {
mp[B[i]]=0;vis[0]=1;dfs(1);mp[B[i]]=-1;vis[0]=0;
if(!flag) {mp[A[i]]=0;vis[0]=1;mp[B[i]]=tot-1;vis[tot-1]=1;dfs(1);}
return 0;
}
F(i,1,n) if((B[i]==C[i])&&A[i]!=B[i]) {
mp[A[i]]=0;vis[0]=1;dfs(1);mp[A[i]]=-1;vis[0]=0;
if(!flag) {mp[B[i]]=0;vis[0]=1;mp[A[i]]=tot-1;vis[tot-1]=1;dfs(1);}
return 0;
}
dfs(1);
return 0;
}

[luogu 1092] 虫食算 (暴力搜索剪枝)的更多相关文章

  1. Luogu P1092 虫食算【搜索/剪枝】 By cellur925

    题目传送门 这道题是一道经久不衰的搜索题目,但是开始做的时候我没什么思路==.初始值-1 输出格式 \(naive\)想法 从右往左依次尝试填充数字,把算式当做一个3行\(n\)列的网格.(什么?你问 ...

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

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

  3. [BZOJ1902]:[NOIP2004]虫食算(搜索)

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

  4. Luogu P1092 虫食算

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

  5. Luogu1092 NOIP2004虫食算(搜索+高斯消元)

    暴力枚举每一位是否进位,然后就可以高斯消元解出方程了.然而复杂度是O(2nn3),相当不靠谱. 考虑优化.注意到某一位进位情况的变化只会影响到方程的常数项,于是可以在最开始做一次高斯消元算出每个未知数 ...

  6. Luogu P1092 虫食算 爆搜

    心路历程:震惊,我竟然得了$90$分!!...康康数据...奥..(忽然有了邪恶的卡数据的想法) 于是把$for(int \space i=0;i<n;++i)$改成了$for(int \spa ...

  7. 【NOIP2004】【CJOJ1703】【洛谷1092】虫食算

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

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

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

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

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

随机推荐

  1. jenkins集成多个项目

    https://www.cnblogs.com/gossip/p/5961376.html 需要jenkins版本高点 安装插件:Multijob plugin

  2. android 细节之 menu 之 invalidateOptionsMenu

    menu 在 android中是个很经常使用的控件,曾经自己做项目的时候通常都是将系统的menu相关方法在activity中直接删去.而且将主题换为fullscreen,然后再在layout中引入自己 ...

  3. Opencv保存摄像头视频&&各种编码器下视频文件占用空间对比

    打开视频文件或摄像头视频需要使用Opencv中的VideoCapture类,保存视频或摄像头视频到本地磁盘,需要使用Opencv中的VideoWriter类,使用都很简单,这篇文章就记录一下Video ...

  4. bzoj4004 [JLOI2015]装备购买——线性基+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 今天讲课讲到的题,据说满足拟阵的性质,所以贪心是正确的: 总之就贪心,按价格从小到大排 ...

  5. 使用 Polyfill 而不再是 bable 来实践js新特性

    现状 我们想要用ES6 语法来写 JavaScript.然而由于我们需要兼容老版本的浏览器,那些浏览器不支持 ES6,我们需要解决这个问题. 有一个标准的做法是:写 ES6 代码 → 将所有代码编译成 ...

  6. Appium + python - automator定位操作

    # coding:utf-8from appium import webdriverfrom time import sleep desired_caps = { 'platformName': 'A ...

  7. JavaScript中变速运动的数学模型构建

    AB两地直线距离相距为S,机器人β从A点向B点行进.已知机器人β的每间隔固定时间行进一段路程,其下次行进的距离为当前距离B点路程的1/q(q为正整数),求机器人第n次行进距离的表达式an以及前n项和公 ...

  8. SpringCloud学习 什么是微服务(一)

    关于SpringCloud,我是看了周老师的<SpringCloud与Docker微服务架构实战>之后才有了一点了解,做下记录,以供后期学习.本人知识有限,如有不对,欢迎批评 1.什么是单 ...

  9. (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如:  List list = new ArrayList();  list.add(“Hello”);  list.add(“World”);  list.add(“Learn”); //此时list 为Hello World Learn  rever

    import java.util.ArrayList; import java.util.List; public class AA { public static void main(String[ ...

  10. linux挂载ntfs格式的U盘

    1.需要安装一个ntfs-3G工具 工具包下载网站:http://www.tuxera.com/community/ntfs-3g-download/ 根据情况选择要下载的包. 2.上传到Linux服 ...