转载自Array98大大的博客

【题目描述】
考古学发现,几千年前古梅文明时期的数学非常的发达,他们懂得多位数的加法和乘法,其表达式和运算规则等都与现在通常所用的方式完全相同(如整数是十进制,左边是高位,最高位不能为零;表达式为中缀运算,先乘后加等),唯一的区别是其符号的写法与现在不同。有充分的证据表明,古梅文明的数学文字一共有13个符号,与 0,1,2,3,4,5,6,7,8,9,+,*,= 这13个数字和符号(称为现代算符)一一对应。为了便于标记,我们用13个小写英文字母a,b,…m代替这些符号(称为古梅算符)。但是,还没有人知道这些古梅算符和现代算符之间的具体对应关系。
在一个石壁上,考古学家发现了一组用古梅算符表示的等式,根据推断,每行有且仅有一个等号,等号左右两边为运算表达式(只含有数字和符号),并且等号两边的计算结果相等。
假设这组等式是成立的,请编程序破译古梅算符和现代算符之间的对应关系。【输入格式】
输入文件的第一行为等式的个数N(1<=N<=1000),以下N行每行为一个等式。
每个等式的长度为5个字符到11个字符。【输出格式】
如果不存在对应关系能够满足这组等式,输出“noway”和一个换行/回车符。
如果有对应关系能够满足这组等式,输出所有能够确定的古梅算符和现代算符的对应关系。每一行有两个字符,其中第一个字符是古梅算符,第二个字符是对应的现代算符。输出按照字典顺序排序。【样例输入】
2
abcdec
cdefe【样例输出】
a6
b*
d=
f+【样例说明】
在上例中,可能对应的现代表达式为{6*2=12,2=1+1},{6*4=24,4=2+2},{6*8=48,8=4+4}。可见,能够确定的对应关系只有a对应6,b对应*,d对应=,f对应+,应该输出;而{c,e}虽然能够找到对应的现代算符使得等式成立,但没有唯一的对应关系,不能输出。其他古梅算符{g,h…m}完全不能确定,也不能输出。【分析】
相比消棋子我觉得还是这道题酸爽一点……毕竟不是单纯的模拟还要敲搜索疯狂的剪枝…………总之我讨厌写搜索,最让人痛恨的是调试搜索TAT
没有充足心里准备不要敲这道题= =反正终归是水过了嘛……下面来讲讲怎么做的。
首先,裸的搜索要敲对吧(PS:爆搜连样例都过不去调试毛线啊……)
这里无视Std各种各样的优化(标程一共敲了600行)然后编写是有一点要注意我们可以优先确定三个操作符的对应关系(体现在代码中的三个for循环,这样搜索就只需要搜数字)第一个优化:搜索时位运算压位,方便编写,加快速度,这个看代码应该都能理解。
第二个优化:其实算不上优化,就是我开始比较蠢……没写位运算,然后就是说把判断放到了搜索完之后……显而易见 O(N!) 连样例都过不了。
第三个优化:确定了运算符之后我们就可以大致确定出等号两边的数的位数,也就是大概的范围,这样可以直接跳过大量不可能的情况。最重要的优化。(对应代码中的Pre_Dfs)
/**************************************************************Problem: 2570User: Array98Language: C++Result: AcceptedTime:136 msMemory:1060 kb
****************************************************************/#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int INF=int(1e9);
const int MaxN=1010;
int T;
char a[MaxN][15];
int len[MaxN],lg2[(1<<10)+10];
int w[15],Ans[15],st[15],cnt[15][MaxN];
bool c1[15],c2[15],mark[15],Map[150][1150];
char Equ,Mul,Add;
bool Solved;inline int Id(char x) { return x-'a'; }int calc()
{int i,sum=0;for(;mark[st[0]-1];st[0]--)st[st[0]-1]=st[st[0]-1]*st[st[0]];for (int i=1; i<=st[0]; i++) sum+=st[i]; st[0]=0;return sum;
}bool check(int d)
{int Last=-1,L=-1,R=-1; st[0]=0;for (int i=1; i<=len[d]; i++){int c=w[Id(a[d][i])];if(c>=0)if(Last>=0)st[st[0]]=st[st[0]]*10+c;else st[++st[0]]=c;else{if(st[0]==0) return 0;for(;mark[st[0]-1];st[0]--)st[st[0]-1]=st[st[0]-1]*st[st[0]];if(c==-3) mark[st[0]]=1;else if(c==-1)L=calc();else mark[st[0]]=0;}Last=c;}R=calc();return L==R;
}void Dfs(int d,int Now,int S)
{bool Flag=1;for (int i=0; i<=12; i++) if(!(Ans[i]==w[i] || Ans[i]==-200)){ Flag=0; break; }if(Flag) return;if(d>T){   Solved=1;for (int i=0; i<=12; i++) if(w[i]!=INF){if(Ans[i]==-100) Ans[i]=w[i];else if(Ans[i]!=w[i])Ans[i]=-200;}else Ans[i]=-200;return;}else{if(Now>len[d]){if(check(d)) Dfs(d+1,1,S);return;}int ch=Id(a[d][Now]);if(w[ch]==INF){for(int S2=S; S2; S2-=S2&-S2){int t=lg2[S2&-S2];if(Now==1 && t==0 && w[Id(a[d][2])]>0)continue;w[ch]=t;Dfs(d,Now+1,S-(S2&-S2));w[ch]=INF;}}else Dfs(d,Now+1,S);}
}int M,lw[15],rw[15];void Get_Range(int &L, int &R)
{ L=R=0; for (;M;M--) L=max(L,lw[M]),R=max(rw[M],R)+(R>0);
}bool Pre_Dfs()
{int Last,L_l,L_r,R_l,R_r;for (int d=1; d<=T; d++){M=0;Last=-1;for (int i=1; i<=len[d]; i++){int c=w[Id(a[d][i])];if(c==INF){ if(Last<0) M++,lw[M]=rw[M]=0; lw[M]++,rw[M]++;}else{if(M==0)return 0;for(; mark[M-1]; M--) lw[M-1]+=lw[M]-1,rw[M-1]+=rw[M];if(c==-3) mark[M]=1;else if(c==-2) mark[M]=0;else if(c==-1) Get_Range(L_l,L_r);}Last=c;}Get_Range(R_l,R_r);if(L_r<R_l || R_r<L_l){return 0;}}return 1;
}int main()
{scanf("%d",&T);for (int i=1; i<=T; i++) scanf("%s",a[i]+1),len[i]=strlen(a[i]+1);for (int i=0; i<=15; i++) lg2[1<<i]=i,Ans[i]=-100;     memset(c1,1,sizeof(c1));for(char i='a';i<='m';i++)for (int j=1; j<=T; j++){bool Flag=1;for (int k=1; k<=len[j]; k++){if(k<len[j]) Map[a[j][k]][a[j][k+1]]=Map[a[j][k+1]][a[j][k]]=1;if(a[j][k]==i) cnt[Id(i)][j]++;}if(cnt[Id(i)][j]!=1) Flag=0;if(a[j][1]==i || a[j][len[j]]==i){ c1[i-'a']=0; Flag=0; }c2[Id(i)]=Flag;}for(Equ='a'; Equ<='m'; Equ++) if(c2[Id(Equ)])for(Mul='a'; Mul<='m'; Mul++) if(c1[Id(Mul)])for(Add='a'; Add<='m'; Add++) if(c1[Id(Add)])if(Equ!=Mul && Add!=Mul && Equ!=Add)if(!Map[Equ][Mul] && !Map[Equ][Add] && !Map[Mul][Add]){                 for (int i=0; i<=12; i++) w[i]=INF;w[Id(Equ)]=-1; w[Id(Add)]=-2; w[Id(Mul)]=-3;if(!Pre_Dfs()) continue;Dfs(1,1,(1<<10)-1);}for (int i=0; i<=12; i++)if(Ans[i]>=-3){putchar('a'+i);if(Ans[i]==-3)putchar('*');else if(Ans[i]==-2)putchar('+');else if(Ans[i]==-1)putchar('=');else putchar('0'+Ans[i]);putchar('\n');}if(!Solved) printf("noway\n");return 0;
}

我自己打了5h,打了6k+,
最后WA了,是在下输了
蒟蒻就是蒟蒻

BZOJ2570:算符破译题解相关推荐

  1. NOI 题目 试题 目录 信奥 历年

    NOI  题目  试题 目录 信奥 历年 NOI  2018 题目  试题 目录 信奥 历年 第一试   2018年7月18日   08:00-13:00 1.归程  return 2.冒泡排序    ...

  2. ZJOI2017 讲课Day1笔记

    额,参考一下大神的笔记.... 地址 http://www.cnblogs.com/ARZhu-NOIpAK/p/6596879.html Day1 2017-3-24 3:34:43 苟-- 富贵 ...

  3. 《算法艺术与信息学竞赛》题目-提交方式对照表 [转]

    id   title how2submit source page 1   盒子里的气球     8 2   图书馆 ural1188   9 3   钓鱼 uva757 pas 13 4   照亮的 ...

  4. 程序设计入门经典题解(百练篇)

    参考链接:PKU百练题解(Bailian) Bailian1017 装箱问题[贪心] - 海岛Blog - CSDN博客 POJ1088 Bailian1088 滑雪[DFS+记忆化搜索]_海岛Blo ...

  5. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛非官方题解

    文章目录 7-1 切蛋糕 7-2 小宝的幸运数组 7-3 上进的凡凡 7-4 Seek the Joker I 7-5 Seek the Joker II 7-6 成绩查询ING 7-7 贪吃的派蒙 ...

  6. BugkuCTF 部分题解(随缘更新)

    之前做的题在BugkuCTF 部分题解(一) 佛系更新 2月3日更新了ezbypass 11月9日更新了奇怪的压缩包 11月7日更新了这个flag,就是逊啦.不可以破译的密码 bugku 佛系更新 M ...

  7. 山东科技大学2020年6月1日作业题解

    山东科技大学2020年6月1日作业题解 题目一: STL--灵活的线性表 Description 数组和链表是我们熟知的两种线性结构,但是它们不够灵活(不能同时实现直接插入.删除和访问操作),给你若干 ...

  8. 华人数学家破译孪生素数猜想 影响或超1+2证明

    2013年05月18日02:59  中国青年报 我有话说(1472人参与) 张益唐近照,由新罕布什尔大学提供 张益唐是个对数字"极其敏感"的人,他能把大学同班同学的出生日期背得&q ...

  9. 遗传编程(GA,genetic programming)算法初探,以及用遗传编程自动生成符合题解的正则表达式的实践...

    1. 遗传编程简介 0x1:什么是遗传编程算法,和传统机器学习算法有什么区别 传统上,我们接触的机器学习算法,都是被设计为解决某一个某一类问题的确定性算法.对于这些机器学习算法来说,唯一的灵活性体现在 ...

最新文章

  1. Linux必学的网络操作命令
  2. 品友互动入榜“AI First——2017-2018年中国人工智能先行企业榜TOP10”
  3. Codeforces Round #331 (Div. 2) A. Wilbur and Swimming Pool 水题
  4. Java配置多数据源access,java联接MS ACCESS,无需配置数据源
  5. 二叉查找树(一)之 C语言的实现
  6. select点击option获取文本输入框的焦点事件
  7. Ext.data.Store 获取Json数据只有一行,而且是最后一行
  8. STM32F103mini基础知识归纳
  9. springboot读取src下文件_java(包括springboot)读取resources下文件方式
  10. union matlab,[转载]intersect,unique,union在matlab中的用法(I lo
  11. 【LINUX C 写文件】
  12. APP移动端自动化测试框架
  13. word制作表格并打印
  14. Xenu工具的简单使用
  15. msxml3.dll 错误 '80072efd' A connection with the server could not be established
  16. 2、Class和Subclass
  17. android 9下载地址,狂野飙车9安卓版下载地址 最新版本下载
  18. btcTrade_project
  19. oracle导入指定字符集入,EXP/IMP 与 字符集、导入导出等
  20. 聚集索引和非聚集索引详解 (zhuang)

热门文章

  1. 利用MATLAB确定幅值裕度和相角裕度:margin命令
  2. sun-JDK、open-JDK的安装
  3. gazebo加载world模型
  4. Linux 常用命令(一)
  5. 不知道变年轻特效软件有哪些?这些有趣的app建议收藏
  6. 第一回:Matplotlib初相识
  7. 一个具有现金折扣系统的软件商城
  8. SAP那些事-职业篇-19-论ERP实施效果的评估
  9. 收银员小票的html布局,小票打印源码(分成一行、二行、三行打印)
  10. powerkey(开关机)实例