搜索问题的关键:优秀的搜索策略以及行之有效的减枝

对于这道题我们阶乘搜肯定不行所以我们按位搜,我们对每一位的三个数进行赋值,然后判解。

对于此一类的搜索乘上一个几十的常数来减枝往往要比直接搜要快得多,因为这样的问题他们都会有一个庞大的"之后",而且判断不存在较为容易,以我们多花一些时间进行减枝往往能达到剪掉许多枝的效果。

搜索还是看感觉,倒搜还是比正搜快......

#pragma GCC optimize("O3")
#include <cstdio>
#include <cstring>
char A[],B[],C[];
int a[],b[],c[],n;
int qian[],hou[],ans[],get[];
bool god;
inline void put_it(){
int len=n;
for(int i=len-;i>=;i--)
a[len-i]=A[i]-'A';
len=strlen(B);
for(int i=len-;i>=;i--)
b[len-i]=B[i]-'A';
len=strlen(C);
for(int i=len-;i>=;i--)
c[len-i]=C[i]-'A';
for(int i=;i<=n;i++)hou[i]=i+,qian[i+]=i;
memset(get,-,sizeof(get)),memset(ans,-,sizeof(ans));
}
inline void dfs(int now,int up){
if(now==n+){
if(!up){
god=;
for(int i=;i<n;i++)printf("%d ",ans[i]);
}
return;
}
if(god)return;
register int temp;
if(ans[a[now]]!=-&&ans[b[now]]!=-){
temp=(ans[b[now]]+ans[a[now]]+up)%n;
if(ans[c[now]]==-&&get[temp]==-)
get[temp]=,ans[c[now]]=temp,dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n),get[temp]=-,ans[c[now]]=-;
else if(ans[c[now]]!=-&&(temp==ans[c[now]]))
dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n);
if(god)return;
return;
}
if(ans[a[now]]==-&&ans[b[now]]==-){
if(a[now]==b[now]){
for(int i=qian[n+];i>;i=qian[i]){
if(get[i-]!=-)continue;
hou[qian[i]]=hou[i],qian[hou[i]]=qian[i],get[i-]=;
ans[a[now]]=i-;
temp=(ans[b[now]]+ans[a[now]]+up)%n;
if(ans[c[now]]==-&&get[temp]==-)
get[temp]=,ans[c[now]]=temp,dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n),get[temp]=-,ans[c[now]]=-;
else if(ans[c[now]]!=-&&(temp==ans[c[now]]))
dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n);
if(god)return;
ans[a[now]]=-;
hou[qian[i]]=i,qian[hou[i]]=i,get[i-]=-;
}
return;
}
for(int i=qian[n+];i>;i=qian[i]){
if(get[i-]!=-)continue;
hou[qian[i]]=hou[i],qian[hou[i]]=qian[i],get[i-]=;
ans[a[now]]=i-;
for(int j=qian[n+];j>;j=qian[j]){
if(get[j-]!=-)continue;
hou[qian[j]]=hou[j],qian[hou[j]]=qian[j],get[j-]=;
ans[b[now]]=j-;
temp=(ans[b[now]]+ans[a[now]]+up)%n;
if(ans[c[now]]==-&&get[temp]==-)
get[temp]=,ans[c[now]]=temp,dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n),get[temp]=-,ans[c[now]]=-;
else if(ans[c[now]]!=-&&(temp==ans[c[now]]))
dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n);
if(god)return;
ans[b[now]]=-;
hou[qian[j]]=j,qian[hou[j]]=j,get[j-]=-;
}
if(god)return;
ans[a[now]]=-;
hou[qian[i]]=i,qian[hou[i]]=i,get[i-]=-;
}
return;
}
if(ans[b[now]]!=-){
for(int i=qian[n+];i>;i=qian[i]){
if(get[i-]!=-)continue;
hou[qian[i]]=hou[i],qian[hou[i]]=qian[i],get[i-]=;
ans[a[now]]=i-;
temp=(ans[b[now]]+ans[a[now]]+up)%n;
if(ans[c[now]]==-&&get[temp]==-)
get[temp]=,ans[c[now]]=temp,dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n),get[temp]=-,ans[c[now]]=-;
else if(ans[c[now]]!=-&&(temp==ans[c[now]]))
dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n);
if(god)return;
ans[a[now]]=-;
hou[qian[i]]=i,qian[hou[i]]=i,get[i-]=-;
}
return;
}
if(ans[a[now]]!=-){
for(int i=qian[n+];i>;i=qian[i]){
if(get[i-]!=-)continue;
hou[qian[i]]=hou[i],qian[hou[i]]=qian[i],get[i-]=;
ans[b[now]]=i-;
temp=(ans[b[now]]+ans[a[now]]+up)%n;
if(ans[c[now]]==-&&get[temp]==-)
get[temp]=,ans[c[now]]=temp,dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n),get[temp]=-,ans[c[now]]=-;
else if(ans[c[now]]!=-&&(temp==ans[c[now]]))
dfs(now+,(ans[b[now]]+ans[a[now]]+up)/n);
if(god)return;
ans[b[now]]=-;
hou[qian[i]]=i,qian[hou[i]]=i,get[i-]=-;
}
return;
}
}
int main(){
scanf("%d%s%s%s",&n,A,B,C),put_it(),dfs(,);
return ;
}

[Noip2004]虫食算 dfs的更多相关文章

  1. NOIP2004 虫食算

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

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

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

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

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

  4. NOIP 2004 虫食算题解

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

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

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

  6. 洛谷 P1092 虫食算 Label:dfs

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

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

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

  8. 【NOIP2004】虫食算

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

  9. 虫食算 2004年NOIP全国联赛提高组(dfs)

    1064 虫食算 2004年NOIP全国联赛提高组  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Descrip ...

随机推荐

  1. 洛谷 P3952

    题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...

  2. JZOJ 5943. 树

    Description

  3. JavaScript 转载

    JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...

  4. Flask初学者:url_for

    URL反转:反转是指通过视图函数名称得到其对应的URL(有反转也就有正转,即通过URL得到视图函数返回的内容,也就是我们平时的访问网页了),需要“url_for(endpoint, **values) ...

  5. Leecode刷题之旅-C语言/python-104二叉树最大深度

    /* * @lc app=leetcode.cn id=104 lang=c * * [104] 二叉树的最大深度 * * https://leetcode-cn.com/problems/maxim ...

  6. Horner规则求多项式

    /* Horner */ /*多项式:A(x)=a[n]X^n+a[n-1]x^n-1+...+a[1]X^1+a[0]X^0*/ #include <stdio.h> long int ...

  7. Java+Selenium3方法篇24-单选和多选按钮操作

    Java+Selenium3方法篇24-单选和多选按钮操作 本篇介绍 webdriver处理前端单选按钮的操作.单选按钮一般叫raido button,就像我们在电子版的单选答题过程一样,单选只能点击 ...

  8. abap<itab>refresh,clear,free

    在ABAP开发过程中,clear,refresh,free都有用来清空内表的作用,但用法还是有区别的. clear itab,清空内表行以及工作区,但保存内存区. clear itab[],清空内表行 ...

  9. MyBatis的笔记

    1.#{}和${}的区别是什么? #{}是预编译处理,${}是字符串替换. #{}是sql的参数占位符,${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替 ...

  10. performance_schema实现套路

      实现中大量使用多层次嵌套预编译,大量if else,wrapper等 不建议去看这个实现 start_mutex_wait_v1 if (flag_thread_instrumentation) ...