enc
【问题背景】
zhx 和他的妹子聊天。
【问题描述】
考虑一种简单的加密算法。
假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母。例如考虑映射规则:
a->b, b->c, c->d, d->a. 那么单词 bad 就会被映射为 cba。这个映射规则的“逆映射规则”为: b->a, c->b, d->c, a->d。 对于密文 cba, 我们很容易将它解密为 bad。
当然,这样的映射需要保证每一个字母映射到的字母是不同的(即不可以出现两个不同的字母映射到同一个字母,否则将会无法解密) 。
一种常见的密码攻击方式被称为已知明文攻击。具体地,在你不知道映射表的情况下,给你一段明文和对应的密文,你可以推导出一些的映射规则,下一次你收到一条密文,你就可能可以解密它。现在你需要完成这样的一个系统。
【输入格式】
第一行包含一个字符串,仅包含小写字母,表示一段明文。
第二行包含一个字符串,仅包含小写字母,表示这段明文对应的密文,保证两行长度相同。
第三行包含一个字符串,仅包含小写字母,表示你需要解密的密文。
【输出格式】
输出共一行,表示输入中第三行密文对应的明文。如果不能解密,输出“ERROR”(不包含引号) 。注意输入可能出现不自恰的情况。
【样例输入】
ab
cc
cc
【样例输出】
ERROR
【样例输入】
ab
ab
c
【样例输出】
ERROR
【样例输入】
abcde
bcdea
cad
【样例输出】
bec
【数据范围与规定】
对于100%的数据,所有字符串长度<=1000。
题解:模拟。水。但是出题人非常阴险,挖了一个坑,那就是当25个密文都有满足条件的对应明文字符时,剩下的那个密文字符与剩下的明文字符对应。就这样丢了10分。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define N 1100 #define ll long long using namespace std; string s1,s2,s3; int l,sum=0; char ans[N]; int ff[30]; bool f[30]={0}; int main() { freopen("enc.in","r",stdin); freopen("enc.ans","w",stdout); cin>>s1>>s2>>s3; l=s2.length(); for (int i=0;i<l;i++) { int x=s2[i]-'a'+1,y=s1[i]-'a'+1; if (!ff[x]&&!f[y]) ff[x]=y,f[y]=1,sum++; else if (ff[x]==y) ff[x]=y; else { cout<<"ERROR"<<endl; return 0; } } if (sum==25)//特判,当25个密文字符都有对应的明文字符时,最后一个密文字符与明文字符相匹配 { int bj; for (int i=1;i<=26;i++) if (!ff[i]) bj=i; for (int i=1;i<=26;i++) if (!f[i]) ff[bj]=i; } l=s3.length(); for (int i=0;i<l;i++) { int j=s3[i]-'a'+1; if (ff[j]) ans[i]=char(ff[j]+'a'-1); else { cout<<"ERROR"<<endl; return 0; } } cout<<ans<<endl; fclose(stdin); fclose(stdout); return 0; }
序
【问题背景】
zhx 给他的妹子们排序。
【问题描述】
zhx 有 N 个妹子,他对第 i 个妹子的好感度为ai, 且所有ai ,两两不相等。现在 N 个妹子随意站成一排,他要将她们根据好感度从小到大排序。他使用的是冒泡排序算法(详见下) 。如果排序过程中好感度为ai的妹子和好感度为aj的妹子发生了交换,那么她们之间会发生一场口角。
现在zhx 想知道,给定妹子的初始排列,在排序完成后,最多存在多少个妹子,她们任意两人之间没发生过口角。
正式地,考虑对数组ai进行冒泡排序,如果ai 和aj 在排序过程中发生交换,那么在两个元素之间连一条边。 你需要求出, 排序结束后, 最多存在多少个元素,其中任意两个元素之间不存在连边。冒牌排序算法如下:
【输入格式】
第一行两个整数 N,表示妹子数量。
接下来一行 N 个整数ai,表示初始第 i 个妹子的好感度。
【输出格式】
一行一个整数,表示最多满足要求的妹子的个数。
【样例输入】
3
3 1 2
【样例输出】
2
【样例解释】
{1, 2}。
【数据规模与约定】
对于30%的数据,1 ≤N ≤ 16。
对于70%的数据,1 ≤ N ≤ 50。
对于100%的数据,1 ≤ N ≤ 100000, 0 ≤ ai < N。
题解:根据冒泡排序的性质,假定i小于j,若ai<aj则两个妹子绝对不会发生交换。因此求出最大上升子序列,他的长度即为答案。求最大上升子序列时,用上二分优化,可将时间降为o(nlogn)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define N 100100 #define ll long long using namespace std; int n,k=0,ans=0; int a[N]; int num[N]={0}; int f[N]; int erfen(int l,int r,int q) { if (l>r) return l; int mid=(l+r)>>1; if (f[mid]>q) erfen(l,mid-1,q); else erfen(mid+1,r,q); } int main() { freopen("sort.in","r",stdin); freopen("sort.ans","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); f[++k]=a[1]; for (int i=2;i<=n;i++) { int j=erfen(0,k,a[i]); f[j]=a[i]; if (j>k) k=j; } cout<<k<<endl; fclose(stdin); fclose(stdout); return 0; }
戏
【问题背景】
zhx 和他的妹子(们)做游戏。
【问题描述】
考虑 N 个人玩一个游戏, 任意两个人之间进行一场游戏 (共 N*(N-1)/2 场) ,且每场一定能分出胜负。现在,你需要在其中找到三个人构成“剪刀石头步”局面:三个人 A,B,C满足 A 战胜 B,B 战胜 C,C 战胜 A。
【输入格式】
第一行一个正整数 N,表示参加游戏的人数。
接下来 N 行,每行 N 个数 0/1,中间没有空格隔开。第 i 行第 j 列数字为 1表示 i 在游戏中战胜了 j。所有对角线元素(即第 i 行第 i 个元素)为 0,保证数据合法。
【输出格式】
如果存在三个人构成“剪刀石头布”局面,输出三个人的编号(从 1 开始) 。
如果不存在这样的三个人,输出一个数-1。
【样例输入】
5
00100
10000
01001
11101
11000
【样例输出】
1 3 2
【数据规模与约定】
对于55%的数据。1 ≤ N ≤ 500。
对于80%的数据,1 ≤ N ≤ 1000。
对于100%的数据,1 ≤ N ≤ 5000
题解:原谅本蒟蒻不会此题,只会打最简单的暴力。弱弱的30分。由于题目没规定输出顺序,本应该能稳过55%的数据,最后只得30分。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define N 5100 #define ll long long using namespace std; int n; char ch; bool f[N][N]={0},ff=1; int main() { freopen("game.in","r",stdin); freopen("game.ans","w",stdout); scanf("%d",&n); scanf("%c",&ch); for (int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%c",&ch); f[i][j]=int (ch-'0'); } scanf("%c",&ch); } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (f[i][j]) for (int k=1;k<=n;k++) if (f[j][k]&&f[k][i]) { cout<<i<<' '<<j<<' '<<k<<endl; return 0; } cout<<-1<<endl; fclose(stdin); fclose(stdout); return 0; }