P1071 潜伏者(字符串 结构体)

本文详细解析了P1071潜伏者问题的解题思路,通过对比加密信息与原文,确保字母一一对应,避免多对一或一对多的情况。利用结构体或pair存储对应关系,采用find函数快速查找,确保26个字母全部出现,最终完成密文翻译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:P1071 潜伏者

题解: 建议看3.0的参考代码。。。。。。
注意点:
  • 加密信息的字母要都在原信息中出现;有没有出现的输出Failed;
  • 原信息或加密信息必须都出现26个字母;小于26个字母输出Failed;
  • 每个字母只能一一对应,不能出现多对一或一对多的情况;出现了则输出Failed;
解释:用一个结构体或pair类型来存储一一对应的字母,方便由加密信息来找原字母;查找原信息中是否存在加密字母可以用for循环来,也可以直接调用string的find函数来找,找不到时返回string::nops; 用vis数组标记是否已经存储过该加密信息,没有存储过则将该组信息存储到结构体或pair中,并令计数器++来保存够不够26个字母;若存储过则看看加密信息对应的原文是否相同,不同则直接Failed结束;相同则再将其存储起来。最后检查一下是否够26个字母,直接使用计数器和26比较即可,若够的话,则将待翻译的密文一一对应的翻译出来;

--------------------------------------------------------------------------------分割线-------------------------------------------------

细节:本来检查26个字母用的是check函数:后来发现其实直接再存储时就进行计数器++即可,汗!!!
bool check()
{
    for(int i = 0; i < s.size(); i++)
        pos[ss[i].first - '0'] = 1;
    for(int i = 'A' - '0'; i <= 'Z' - '0'; i++)
        if(pos[i] == 0) return false;
    return true;
}
参考代码:1.0 用pair实现,可以用struct结构体实现!!!都可以的!

string的find函数找不到返回string::npos;

#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

typedef pair<char, char> PP;
string str, s, t;
PP ss[110];
int k, pos[100], j;
bool vis[100];

PP get_c(char c)
{
    for(int i = 0; i < s.size(); i++)
        if(ss[i].first == c) return ss[i];
}

bool check()
{
    for(int i = 0; i < s.size(); i++)
        pos[ss[i].first - '0'] = 1;
    for(int i = 'A' - '0'; i <= 'Z' - '0'; i++)
        if(pos[i] == 0) return false;
    return true;
}

int main()
{
    cin >> s >> str >> t;
    for(int i = 0; i < s.size(); i++)
    {
        if(str.find(s[i]) == string::npos)
        {
            cout << "Failed" << endl;return 0;
        }
        if(vis[s[i] - '0'])
        {
            PP r = get_c(s[i]);
            if(r.second != str[i]) {cout <<"Failed"<<endl; return 0;}
            else ss[i] = {s[i], str[i]};
        }
        else ss[i] = {s[i], str[i]}, vis[s[i] - '0'] = true, j++;
    }
    //直接j++计数就行,当然check函数也是对的
    //if(!check()) {cout << "Failed" << endl;return 0;}
    if(j < 26) {cout << "Failed" << endl;return 0;}
    for(int i = 0; i < t.size(); i++)
    {
        PP r = get_c(t[i]);
        cout << r.second;
    }
    return 0;
}

参考代码2.0: 结构体实现,就改了一下;string的查找改了一下;
typedef struct Node
{
    char first, second;
}PP;

完整代码:

#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

typedef struct Node
{
    char first, second;
}PP;

string str, s, t;
PP ss[110];
int k, pos[100], j;
bool vis[100];

PP get_c(char c)
{
    for(int i = 0; i < s.size(); i++)
        if(ss[i].first == c) return ss[i];
}

int Find(char c)
{
    for(int i = 0; i < str.size(); i++)
        if(str[i] == c) return 1;
    return 0;
}

int main()
{
    cin >> s >> str >> t;
    for(int i = 0; i < s.size(); i++)
    {
        if(!Find(s[i]))
        {
            cout << "Failed" << endl;return 0;
        }
        if(vis[s[i] - '0'])
        {
            PP r = get_c(s[i]);
            if(r.second != str[i]) {cout <<"Failed"<<endl; return 0;}
            else ss[i] = {s[i], str[i]};
        }
        else ss[i] = {s[i], str[i]}, vis[s[i] - '0'] = true, j++;
    }
    if(j < 26) {cout << "Failed" << endl;return 0;}
    for(int i = 0; i < t.size(); i++)
    {
        PP r = get_c(t[i]);
        cout << r.second;
    }
    return 0;
}
参考代码:3.0 struct实现,相较于前两个更好理解,清晰。。。。
#include <iostream>
#include <cstring>
using namespace std;

char before[110],after[110],word[110];
int vis[27];
struct Node
{
	char b,a;
};
Node T[27];

Node get_c(char c)
{
	for(int i = 0; i < 26; i++)
		if(T[i].a == c)
			return T[i];
}

int main()
{
	cin >> after >> before >> word;
	for(int i=0;i<strlen(before);i++)
	{
		if(vis[before[i]-'A']==1)
		{
			if(T[before[i] - 'A'].a != after[i])
			{
				cout<<"Failed"<<endl;
				return 0;
			}
			else continue;
		}
		T[before[i] - 'A'] = {before[i], after[i]};
		vis[before[i]-'A']=1;
	}
	for(int i=0;i<26;i++)
	{
		if(!vis[i])
		{
			cout<<"Failed"<<endl;
			return 0;
		}
	}
	for(int i=0;i<strlen(word);i++)
	{
		Node t = get_c(word[i]);
		cout << t.b;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值