FYWOO求助

P1055 [NOIP2008 普及组] ISBN 号码

LBS6307 @ 2024-09-26 20:12:57

ISBN不会写 大佬们请原谅我才学C++不到三个月 但是AC不了 求大佬帮助

#include<bits/stdc++.h>
using namespace std;
int digit[9];
int main()
{
    int i,s,b,n,sum,r,bi,bs,bb,bn;
    char g1,g2,g3;
    cin >> i >> g1 >> s >> g2 >> b >> g3 >> n ;
    bi = i;
    bs = s;
    bb = b;
    bn = n;
    digit[1]=i;
    for (int x=2;x<=4;x++){
        digit[x]=s%10;
        s/=10;
    }    
    for (int j=5;j<=9;j++){
        digit[j]=b%10;
        b/=10;
    }    
    for (int u=1;u<=9;u++){
        digit[u]=digit[u]*u;
        sum+=digit[u];
    }
    r = sum%11;
    if(n==r){
        cout << "Right";
    }
    else{
        cout << bi << g1 << bs << g2 << bb << g3 << r ;
    }    
    return 0;
}

求救


by Niko_online_ @ 2024-09-28 20:39:48

Receive!以下是本蒟蒻的修改过程,希望你可以从中获益OwO

尝试过程

  1. 拿到代码,首先可以看到g1,g2,g3三个char类型的变量,但其实想将 '-' 单独摘出没有这么复杂,这样就可以了:

    char g;
    cin >> i >> g >> s >> g >> b >> g >> n ;
  2. 对于's'和'b'两个整数分离各数位并存入digit数组的方法不当。原代码见下:

    for (int x=2;x<=4;x++){
    digit[x]=s%10;
    s/=10;
    }    
    for (int j=5;j<=9;j++){
    digit[j]=b%10;
    b/=10;
    }

    但事实上,如果输入是0-670-82162-4,那么s = 670,b = 82162,先进digit数组的应该是他们的个位 (digit[x]=s%10) ,故插入所有的数字之后的digit数组是: {0,0,7,6,2,6,1,2,8} ,明显有误。

  3. ISBN号码的识别码部分存在“10”这个数字,并用“X”来代替,在代码中并没有指出。

结合上述三点,我写出了以下这个代码:

#include<bits/stdc++.h>
using namespace std;
int digit[9];
int main()
{
    int i,s,b,sum,r,bi,bs,bb,bn;
    char g,n; 
    cin >> i >> g >> s >> g >> b >> g >> n ;
    bi = i;
    bs = s;
    bb = b;
    bn = (n=='X'?10:(int)n-'0');//判断识别码是否为"X"
    digit[1]=i;
    for (int x=4;x>=2;x--){//每次将个位反向插入digit数组
        digit[x]=s%10;
        s/=10;
    }
    for (int j=9;j>=5;j--){//同理
        digit[j]=b%10;
        b/=10;
    }
    for (int u=1;u<=9;u++){
        digit[u]=digit[u]*u;
        sum+=digit[u];
    }
    r = sum%11;
    if(bn==r){
        cout << "Right";
    }
    else{
        char rr;
        if(r==10)rr='X';
        else rr=r+'0';//将识别码转化为字符类型,将r==10的情况单独指出
        cout << bi << g << bs << g << bb << g << rr ;
    } 
    return 0;
}

没想到,这个代码却只得到了#4的10分QAQ

正确示范

  1. 总结经验,我发现了一个致命的问题:
    cin >> i >> g1 >> s >> g2 >> b >> g3 >> n ;

    在这一行中,i,s,b,n四个变量都是整数类型,但是如果存在这样一个测试点呢?

5-004-00123-7

很明显,这样得到的s=4,b=123,如果就这样代入,那么后面的digit数组就也是错误的了。对此,我使用了string来改善代码。

  1. 在原代码中,用到了"+=""/="的变量有s,b,sum。但是这些变量的定义却随意的放在了main函数的内部,这样做就像是把定义数组放在了函数内部一样,初始值99.99% 不是0。因此,将这一行放在main函数的外面更好。

针对以上几点,我修改了代码(稍微有一点狠),并成功拿到了AC,代码如下:

#include<bits/stdc++.h>
using namespace std;
int digit[20];
//因为你的数组是从1而不是从0开始用,并且
//每个数组后面都有终止符\0,只开9个位置肯定是放不下的hh 
int n,sum,r;//定义放在外面才能初始化为0 
int main()
{
    //int i,s,b,bi,bs,bb,bn;
    string all;
    cin>>all;//将整个ISBN号码整体输入 
    for(int i=0,t=1;i<(int)all.size()-1;i++){//只要该项不是"-",就直接插入到 digit数组中 
        if(all[i]!='-')digit[t++]=all[i]-'0';//字符转数字需要减去一个字符'0'(详情可搜索ASCII码) 
    }
    char n1 = all[all.size()-1];//将输入的识别码作为字符存起来 
    n = n1=='X'?10:(int)n1-'0';//处理识别码 
    /*
    digit[1]=i;
    for (int x=2;x<=4;x++){
        digit[x]=s%10;
        s/=10;
    }    
    for (int j=5;j<=9;j++){
        digit[j]=b%10;
        b/=10;
    }
    */
    for (int u=1;u<=9;u++){
        int res = digit[u]*u;
        sum+=res;
    }
    r = sum%11;
    if(n==r){
        cout <<"Right"<<endl;
    }
    else{
        for(int i=1;i<=9;i++){
            cout<<digit[i];
            if(i==1||i==4||i==9)cout<<"-";//稍微改进了一下输出 
        }
        if(r==10)cout<<'X'<<endl;//识别码的输出 
        else cout<<r<<endl;
    }
    return 0;
}

by LBS6307 @ 2024-10-09 13:19:30

@Niko_online_谢啦我试试


|