求教:一道NOI试题,我这个解法为什么只有9分。

清晨曦月
博客专家认证
2016-12-20 10:33:11
试题:
http://noi.openjudge.cn/ch0107/11/
思路就是从v,e得到key保存在k里面。然后解密w。
我看了一些代码,用一个f标记数组表示k中对应位是否被填充。我的代码中k的元素初始都是0,代表未获取信息,在得到新的解密信息时,设置k并用ecnt记录解密已解密多少字符。思路应该没问题啊,也验证了很多组输入,但是只有9分。

问题:我的代码错在哪里?



#include<iostream>
#include<cstring>
using namespace std;

int main(){
char v[100],e[100],w[101],k[26]; //v是信息,e是加密信息,w是待解密信息。
memset(k,0,sizeof(k));
memset(w,0,sizeof(w));
int i,len,tmp,ecnt=0;
cin>>e>>v>>w;
len=strlen(e);
if(len<26){
cout<<"Failed";
return 0;
}
for(i=0;i<len;i++){
tmp=e[i]-'A';
if(k[tmp]==0){
k[tmp]=v[i];
ecnt+=1;
}else if(k[tmp]!=v[i]){
cout<<"Failed";
return 0;
}
}
if(ecnt!=26){
cout<<"Failed";
return 0;
}
len=strlen(w);
for(i=0;i<len;i++){
w[i]=k[w[i]-'A'];
}
cout<<w;
}
...全文
248 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
cutmelon 2016-12-21
  • 打赏
  • 举报
回复
改的有点匆忙了,最后解密那里应该有判断码表是不是能解的
#include<iostream>

using namespace std;

int main()
{
	char v[101],e[101],w[101],k[26],o[101]; //v是信息,e是加密信息,w是待解密信息。
	memset(v,0,sizeof(v));
	memset(k,0,sizeof(k));
	memset(w,0,sizeof(w));
	memset(o,0,sizeof(o));

	cin>>e>>v>>w;
	if (strlen(e)==strlen(v))
	{
		bool good=true;
		//构造密码表
		for (int i=0;i<strlen(e);i++)
		{
			int tmp=e[i]-'A';
			if (k[tmp]!=0&&k[tmp]!=v[i])
			{
				//存在重复码
				good=false;
				break;
			}
			k[tmp]=v[i];
		}
		if (good)
		{
			//解密
			for (int i=0;i<strlen(w);i++)
			{
				if (k[w[i]-'A'])
					o[i]=k[w[i]-'A'];
				else
				{
					good=false;
					break;
				}
			}
			if (good)
			{
				cout<<o<<endl;
				return 1;
			}
		}
	}
	cout<<"Failed"<<endl;
	return 0;
}
cutmelon 2016-12-21
  • 打赏
  • 举报
回复
我觉得你的错误应该是死抠26不放了,题目没说26个字母一定全用上啊
#include<iostream>

using namespace std;

int main()
{
	char v[101],e[101],w[101],k[26]; //v是信息,e是加密信息,w是待解密信息。
	memset(v,0,sizeof(v));
	memset(k,0,sizeof(k));
	memset(w,0,sizeof(w));

	cin>>e>>v>>w;
	if (strlen(e)==strlen(v))
	{
		bool good=true;
		//构造密码表
		for (int i=0;i<strlen(e);i++)
		{
			int tmp=e[i]-'A';
			if (k[tmp]!=0&&k[tmp]!=v[i])
			{
				//存在重复码
				good=false;
				break;
			}
			k[tmp]=v[i];
		}
		if (good)
		{
			//解密
			for (int i=0;i<strlen(w);i++)
				cout<<k[w[i]-'A'];
			cout<<endl;
			return 1;
		}
	}
	cout<<"Failed"<<endl;
	return 0;
}
赵4老师 2016-12-21
  • 打赏
  • 举报
回复
边界条件 输入输出格式 ……
清晨曦月 2016-12-21
  • 打赏
  • 举报
回复
测试数据: ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYY
清晨曦月 2016-12-21
  • 打赏
  • 举报
回复
我想,我找到原因了。 我的代码只统计了明文多对1,没有统计密文多对1.加一个校验就可以了。
	for(i=0;i<len;i++){
		t=e[i]-'A';
		th=v[i]-'A';
		if((k[t]==0) && (kh[th]==0)){
			k[t]=v[i];
			kh[th]=e[i];
			ecnt+=1;
		}else if((k[t]!=v[i]) || (kh[th]!=e[i])){
			cout<<"Failed";
			return 0;
		}
	}
清晨曦月 2016-12-21
  • 打赏
  • 举报
回复
不是吧,我感觉有说破译26个字母才行啊…… 如此进行下去直到停止于如下的某个状态: 1、 所有信息扫描完毕,‘A’—‘Z’所有26个字母在原信息中均出现过并获得了相应的“密字”。 2、 所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出现。 3、 扫描中发现掌握的信息里有明显的自相矛盾或错误(违反S过密码的编码规则)。例如某条信息“XYZ”被翻译为“ABA”就违反了“不同字母对应不同密字”的规则。 输出 共1行。 若破译密码停止时出现2,3两种情况,请你输出“Failed”(不含引号,注意首字母大写,其它小写)。
清晨曦月 2016-12-20
  • 打赏
  • 举报
回复
额,开始是100来着,以为是结尾啥的的问题,就加了一点……可惜并没有什么卵用
xskxzr 2016-12-20
  • 打赏
  • 举报
回复
为啥v的长度是100,w的长度是101?

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧