洛谷 P1071 潜伏者(字符串模拟)

题目链接:https://www.luogu.org/problemnew/show/P1071
题意:给你一串加密后的大写字母,和对应的明文,根据以下规则判断密-明对应有无漏洞:
1. 每个字母只对应一个唯一的“密字”,不同的字母对应不同的“密字”。“密字”可以和原字母相同。
2. 所有信息扫描完毕,‘A’-‘Z’ 所有 26 个字母在原信息中均出现过并获得了相应的“密字”。
意思就是说原字和密字只能一对一,而且26个字母都要有。
还有一个任务就是把他给你的一段密文翻译成明文
伪代码如下:

if(原文和密文中26个大写字母都出现过){
    if(存在漏洞){
        cout<<"Failed"<<endl;
    }
    else
        执行翻译;
}
else
    cout<<"Failed"<<endl

所以主要任务就是把上述伪代码中的三个函数写出来。
代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
string x,y,c;
char k[26];//存26个字母
char a[26];
bool is_26(string x){//判断是否26个字母都出现了
    int a1[26]={0};
    if(x.length()<26)
        return 0;
    else{
        for(int i=0;i<x.length();i++){
            int p=x[i]-'A';
            a1[p]++;//出现了就加1
        }
        for(int i=0;i<26;i++){
            if(a1[i]==0)//有一个没出现就return 0
                return 0;
        }
        return 1;//否则return 1
    }
}
bool is_leak(string x,string y){//x为密文,y为原文
    for(int i=0;i<26;i++){
        a[i]='0';//a[i]表示i对应字母的原文,如1对应B,那么B就是a[1]的密文
    }//初始置为'0'
    int len=x.length();
    int i,j;
    for(i=0;i<len;i++){
        int p=x[i]-'A';//下标
        if(a[p]!='0'){//如果这个密文的原文出现过
            if(a[p]!=y[i])//新和旧不一样就return 1
                return 1;
        }
        if(a[p]=='0'){//没出现过
            for(j=0;j<26;j++){
                if(j!=p&&a[j]==y[i]){在a[]中有其它和这个一样的
                    return 1;
                }
                a[p]=y[i];//没有,那就是置为这个
            }
        }
    }
    return 0;
}
void Translate(string x){
    for(int i=0;i<x.length();i++){
        cout<<a[x[i]-'A'];//输出
    }
}
int main(){//以下是主程序,上面伪代码中已经很清楚了
    cin>>x>>y>>c;
    for(int i=0;i<26;i++){
        k[i]=i+'A';
    }
    if(is_26(x)&&is_26(y)){
        if(is_leak(x,y)){
            cout<<"Failed"<<endl;
        }
        else{
            Translate(c);
        }
    }
    else
        cout<<"Failed"<<endl;
return 0;
}

总结:此题核心是有无漏洞的写法。

猜你喜欢

转载自blog.csdn.net/yczhaoxun/article/details/79851537