[HAOI2005] 破译密文
个人最怕字符串和DP,我从来没想过这题拿并查集写。
一开始我是填格子的思路,往每一个位置填0,1,最后不能确定的位置的个数进行2的幂次就是答案,之后发现没法填,就输出0。
正解是并查集,思想也是逐位分析,借助并查集这个工具。最巧妙的也是解题关键的地方就是把每个代表多位的密码拆成一位一位的,这样一来每个字母只代表一个位置。便可以逐位分析了。
先考虑无解的情况:
1:两段密文长度不一样。
2:某个位置上出现0对1或1对0。
之后我们考虑逐位分析:
在有解的情况下,对应位置所代表的数字一定是相同的,不同位置用同样字母表示那这两个位置也是相同的,这样我们便建立了不同位置相同字母和不同字母相同位置这两对关系,借助这两对关系我们可以得到字母间的等价关系。
利用并查集把相同位置的字母并到一个集合中,表示这两个字母代表相同的数字,最后我们会得到代表0的字母集合,代表1的字母集合,和n个即可以代表0又可以代表1的集合,这时候答案就是2n。
需要注意的一点是在最后统计集合时,只考虑在密文中出现过的密码,就像样例中b这个密码并没有出现,但是如果统计上了便会多出来50个不确定集合,也就无法得出正确解了。
// q.c
// 居然又把并查集写挂了~#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int N=27,K=107,M=10000+7;
int n,cnt=1,ans,len[N],f[M],w[N][K];
char c,s1[M],s2[M];
vector<int> text1,text2;
bool vis[M];
void reset() {for(int i=0;i<=cnt;i++) f[i]=i;
}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);
}
void solve(char *s,int &leng,vector<int> &a) {for(int i=0;i<leng;i++) {if(s[i]=='0'||s[i]=='1') a.push_back(s[i]-'0');else for(int j=1;j<=len[s[i]-'a'];j++) {vis[w[s[i]-'a'][j]]=true;a.push_back(w[s[i]-'a'][j]);}}leng=a.size();
}
int main() {freopen("encrypt.in","r",stdin);freopen("encrypt.out","w",stdout);cin>>s1>>s2>>n;int len1=strlen(s1);int len2=strlen(s2);for(int i=1;i<=n;i++) {cin>>c; cin>>len[c-'a'];for(int j=1;j<=len[c-'a'];j++) w[c-'a'][j]=++cnt;}solve(s1,len1,text1);solve(s2,len2,text2);if(len1!=len2) {cout<<0<<endl;return 0;} else {int x,y,fx,fy;reset();for(int i=0;i<len1;i++) {x=text1[i],y=text2[i],fx=find(x),fy=find(y);if(fx!=fy) {if(fx==0&&fy==1||fy==0&&fx==1) {cout<<0<<endl;return 0;}if(fx==0||fx==1) f[fy]=fx; // 改根节点.else f[fx]=fy;}}for(int i=2;i<=cnt;i++) f[i]=find(i);for(int i=2;i<=cnt;i++) if(vis[i]&&f[i]==i) ans++;}cout<<(1<<ans)<<endl;return 0;
}
没错我第一次交的时候又把并查集写挂了......
转载于:https://www.cnblogs.com/qjs12/p/8672552.html
[HAOI2005] 破译密文相关推荐
- 【并查集】HAOI破译密文
[问题描述] 信息的明文是由0利1组成的非空序列.但在网络通信中,为了信息的安全性,常对明文进行加密,用密文进行传输.密文是由0.1和若干个密码字母组成,每个密码字母代表不同的01串,例如,密文=01 ...
- java文件加密解密实验报告_《网络信息安全技术》_实验报告_破译vigenamp#232;re_密码加密的密文...
<<网络信息安全技术>_实验报告_破译vigen&#232;re_密码加密的密文>由会员分享,可在线阅读,更多相关<<网络信息安全技术>_实验报 ...
- Windows脚本编码器算法分析与破译
Windows脚本编码器算法分析与破译 作者:lake2 大家对脚本一定很熟悉吧,呵呵,脚本编写简单无需编译所以非常方便.不过,脚本的一个缺点是它不能保护脚本的内容,因为随便谁拿到一个脚本程序都可以用 ...
- 数据安全学习概念理解——明文与密文的区别
1.定义 明文,bai是指没有加密的文字(du或者字符串),一般人都能看zhi懂的意思,在通信系dao统中它可能是比特流,如文本.位图.数字化的语音或者数字化的视频图像等.密文是加了密的的文字,明文是 ...
- 由文章中英文字母出现频率分析破解密文
原题: 使用频率分析法,尝试破译密文: WB WI KJB MK RMIT BMIQ BJ RASHMWK RMVP YJERYRKB MKD WBI IWOKWXWVMKVR MKDIJYR YNI ...
- 量子信息技术研究现状与未来——郭光灿
来源: 中国科学杂志社 量子信息技术是量子力学与信息科学融合的新兴交叉学科, 它的诞生标志着人类社会将从经典技术迈进到量子技术的新时代, 本文将阐述量子信息技术的研究现状与未来. 文中描绘了量子技术发 ...
- 密码学基本概念(一)
区块链兄弟社区,区块链技术专业问答先行者,中国区块链技术爱好者聚集地 作者:于中阳 来源:区块链兄弟 原文链接:http://www.blockchainbrother.com/article/72 ...
- 浅谈对称加密与非对称加密
在数字加密算法中,通过可划分为对称加密和非对称加密. 一:什么是对称加密? 在对称加密算法中,加密和解密使用的是同一把钥匙,即:使用相同的密匙对同一密码进行加密和解密: 加密过程如下: 加密:原文 + ...
- 【网络信息安全】密码学入门笔记
密码学入门 主要内容与重点 一.传统密码学 二.现代密码学 三.理论不可破解和计算不可破解的加密算法 密码系统的基本要求和设计原则 一次一密密码系统 一次一密码系统的算法 一次一密密码系统举例 无法破 ...
最新文章
- 眉目传情之匠心独运的kfifo【转】
- DUMP3 企业级电商项目
- 【SVM】A Practical Guide to Support Vector Classication
- Runtime底层原理--Runtime简介、函数注释
- 关于区块链技术的10本书
- HDU 2602.Bone Collector-动态规划0-1背包
- java web项目中连接mysql数据库,javaweb之eclipse工程连接mysql数据库
- Java加密与解密的艺术~数字证书~证书管理
- mysql与citespace_CiteSpace与MySQL数据库的连接-科学网—博客.PDF
- Producer Flow Control 和 vmQueueCursor
- [Node.js]操作mysql
- (2015省赛系列--团体热身赛第二场)
- 爬虫(二)—解析真实网页(猫途鹰)
- 代理应用好文两篇(1)
- 人口logistic模型公式_人口的logistic模型
- 新路由3 newifi3 官方固件与离线插件合集
- labelme为圆环状物体打标签【tips】
- HTML页面SVG的使用
- 【看好了】如何使用fiddler实现手机抓包,Filters过滤器!
- 知识分享:电脑可以使用的pdf翻译软件哪个好用?
热门文章
- delphi控件切图界面闪烁_「这个控件叫什么」系列之加载占位图+页面指示器
- linux c openssl aes 加解密
- AMBA APB总线协议(APB4)
- 顺序消费可没你想的这么简单,队列数量的变更往往无法保证同一个账号的消息发送到同一个分区,怎么解决?
- linux 脚本含参,linux shell脚本文件的入参
- 面试小结一:关于操作系统的面试题整理
- ENDNOTE使用方法(转发)
- Ubuntu下tar命令使用详解 .tar解压、.tar压缩
- 【赛氪 Saikr】不正方形(数学、平面几何 ps:今天打了假赛)
- ipadmini5可以安装eclipse嘛_MyEclipse 2017软件安装教程