NOIP2009 提高组 复赛 spy 潜伏者

NOIP2009 提高组 复赛 spy 潜伏者

1.很快读懂题意,想用C++里的map但忍住了。采用数学中的映射关系,'A'-0,'B'-1,'C'-2依次类推。

2.开一个密码明码对应数组,a[i]=k,i是密码,对应字母i+'A',k是明码,对应字母k+'A'。

3.初始化时,将a数组中的数值初始化为-1,因为'A'-0。

4.再次遇到a[j]时,若a[j]!=k,表明一个密码对应两个字母。

5.若count==26,表明26个字母都统计到了。

6.写代码时,小错误不断,如for循环忘记写花括号,忘记了j=s3[i]-'A',查了个半天。

7.三个样例通过后,提交90分,很是满意,考试时,应该不会为了没拿到的10分停留了,继续下一道。

耗时:30分钟。

8.搜索网络,发现http://wenku.baidu.com/link?url=mc1Mdx_N2Dy2Gld11CzsG23lmwL7FuBzKMvy39LsS7Kls6Up123QpldGbKV8X1MeQRIOLy6ARJmjtGYOfbKDICaZ2RUZ5gcfkiQhcOdfF3e与本人问题一致:(本人考试的时候想不到啊)

需要注意不僅要判斷是否每一個密文字母都存在惟一對應的明文字母,還要判斷是否每一個明文字母都存在惟一對應的密文字母。(去年我沒判斷這個,
所以測試點三WA了,九十分)

9.马上进行修改:再开了一个明码的数组b[26]。

难度:90分,简单

难度:100分,难

附上AC代码,编译环境Dev-C++4.9.9.2

//2009 syp
#include <stdio.h>
#include <string.h>
int main(){
    char s1[100+10],s2[100+10],s3[100+10];
    int a[26];//26个字母
    int b[26];
    int len1,len3;
    int i,j,k;//字母到数字的映射
    int count=0;
    scanf("%s%s%s",s1,s2,s3);
    memset(a,-1,sizeof(a));
    memset(b,-1,sizeof(b));
    len1=strlen(s1);
    len3=strlen(s3);
    for(i=0;i<len1;i++){
        j=s1[i]-'A';
        k=s2[i]-'A';
        if(a[j]==-1&&b[k]==-1){
            a[j]=k;
            b[k]=j;
            count++;//统计字母
        }else if(a[j]!=k||b[k]!=j)//已赋值
            break;
    }
    if(i==len1){//s1中每个字母都遍历了
        if(count==26){
            for(i=0;i<len3;i++){
                j=s3[i]-'A';
                printf("%c",a[j]+'A');
            }
            printf("\n");
        }else//没到26个字母
            printf("Failed\n");
    }else{
        printf("Failed\n");
    }
    return 0;
}



附上90分代码,编译环境Dev-C++4.9.9.2

//2009 syp
#include <stdio.h>
#include <string.h>
int main(){
    char s1[100+10],s2[100+10],s3[100+10];
    int a[26];//26个字母
    int len1,len3;
    int i,j,k;//字母到数字的映射
    int count=0;
    scanf("%s%s%s",s1,s2,s3);
    memset(a,-1,sizeof(a));
    len1=strlen(s1);
    len3=strlen(s3);
    for(i=0;i<len1;i++){
        j=s1[i]-'A';
        k=s2[i]-'A';
        if(a[j]==-1){
            a[j]=k;
            count++;//统计字母
        }else if(a[j]!=k)//已赋值
            break;
    }
    if(i==len1){//s1中每个字母都遍历了
        if(count==26){
            for(i=0;i<len3;i++){
                j=s3[i]-'A';
                printf("%c",a[j]+'A');
            }
            printf("\n");
        }else//没到26个字母
            printf("Failed\n");
    }else{
        printf("Failed\n");
    }
    return 0;
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值