这里是用c的,求助

P1055 [NOIP2008 普及组] ISBN 号码

sduoooh @ 2021-11-09 23:07:27

代码如下,只有一个ac。。。

#include <stdio.h>
#include <ctype.h>
int main (){
    int a,b,c,d,e,f,g,h,i,j,k;
    char x;
    scanf ("%d-%d%d%d-%d%d%d%d%d-%c",&a,&b,&c,&d,&e,&f,&g,&h,&i,&x);
    j=a+b*2+c*3+d*4+e*5+f*6+g*7+h*8+i*9;
    int l=toascii (x);
    k=j%11;
    if (k==10&&l==88){
        printf ("Right");
        return 0;
    }
    if (k==10&&l!=88){
        printf ("%d-%d%d%d-%d%d%d%d%d-x",a,b,c,d,e,f,g,h,i);
        return 0;
    }
    else {
        if (k==x||l==88){
            printf ("Right");
            return 0;
        }
        if (k!=x||l==88){
            printf ("%d-%d%d%d-%d%d%d%d%d-%d",a,b,c,d,e,f,g,h,i,k);
            return 0;
        }
    }
    return 0;
}

by ud2_ @ 2021-11-09 23:41:11

scanf 输入时,%d 会尽量多读。要一次只读一个字符可以写 %1d 或者 %c

下面的计算中,先算出应该作为识别码的字符再比较会方便些:

int j = (a + b * 2 /* … */ + i * 9) % 11;
char k = j == 10 ? 'X' : '0' + j;
if (k == x) {
  // …
} else {
  // …
}

注意数字(6)和表示它的字符('6')是不一样的,两者之间转换可通过加减 '0'a ? b : c 表示如果条件 a 成立就以 b 为结果,否则用 c。不要用 toascii


by sduoooh @ 2021-11-10 13:56:00

@ud2_ 谢谢!但是我尝试了一下,比如说这样的代码:

#include <stdio.h>
int main (){
    int a,b,c,d,e,f,g,h,i,j;
    char x,l;
    scanf ("%1d%1d%1d%1d%1d%1d%1d%1d%1d%c",&a,&b,&c,&d,&e,&f,&g,&h,&i,&x);
    j=(a+b*2+c*3+d*4+e*5+f*6+g*7+h*8+i*9)%11;
    l=j==10?"X":"0"+j;
    if (l==x){
        printf ("Right");
        return 0;
    }
    else {
        printf ("%d-%d%d%d-%d%d%d%d%d-%c",a,b,c,d,e,f,g,h,i,l);
        return 0;
    }
    return 0;
}

他也是wa,我于是就有点摸不清楚是不是读入的时候那个减号的问题,以及您这里提供的“尽量多读”链接里,我也看到了也许“-”本身会干扰读入,接下来我就尝试看看能不能用数组或者用函数的方式来解决这个问题,看看是否是读入的逻辑出了问题,总之谢谢!


by ud2_ @ 2021-11-10 14:24:51

@sduoooh 格式串里写减号意思是“下个字符是减号,请跳过这个字符”。%1d 则是“接下来 1 个字符以整数开头,请读入这个整数”。实际上一个 %1d 后,下一个字符是 -

字符('X')和包含它的字符串("X")也是不一样的。后者相当于数组 (char[]) {'X', 0}


by sduoooh @ 2021-11-10 15:24:58

@ud2_ 感谢!我刚刚的尝试里想用数组来规避也许存在的-对读入的干扰,结果弄了半天,沿着这个思路走,缝缝补补,最好只有3个ac

#include <stdio.h>
int main (){
    /*char s[10];*/
    char s[13];
    char k;
    int i,sum,m;
    /*for (i=0;i<=9;i++){
        char l;
        scanf ("%c",&l);
        if (l=="-")
            continue;
        else 
            s[i]=l;
    }*/
    for (i=0;i<=12;i++){
        char l;
        scanf ("%c",&l);
        s[i]=l;
    }    
    /*for (i=0;i<=8;i++){
        sum+=s[i]-"0";
        if (i==8)
            m=sum%11;
    }*/
    for (i=0;i<=12;i++){
        if (i==1||i==5||i==11)
            continue;
        sum+=s[i]-'0';
        if (i==12)
            m=sum%11;
    }
    char k=m==10?'x':'0'+m;
    /*if (k==s[10]){
        printf ("Right");
        return 0;
    }*/
    if (k==s[12]){
        printf ("Right");
        return 0;
    }
    else {
        for (i=0;i<=11;i++){
        printf ("%c",s[i]);
        }
        printf ("%c",k);
        return 0;
    }
    return 0;
}

然后刚刚看见您这个回复,我又回去找了最开始那个,加上后来您说的对一些地方进行的修补和改进的核心代码,最终在保留了-和把“改成‘等等情况下全ac了(此处应当有一个笑哭) 谢谢!


by G15010709265 @ 2021-11-26 16:40:44


#include <stdio.h>
main()
{
    int isbn [13];
    char plus[13];
    int i;
    int sum;
    int test;

    for (i = 0 ; i<13 ; i++){
        scanf("%c",&plus[i]);
    }
    for (i = 0 ; i<13 ; i++){
        isbn[i] = plus[i] - '0';
    }
    sum = isbn[0]+2*isbn[2]+3*isbn[3]+4*isbn[4]+5*isbn[6]+6*isbn[7]+7*isbn[8]+8*isbn[9]+9*isbn[10];
    test = (sum%11);

    if (test == isbn[12] || isbn[12]==40&&test==10){
        printf("Right");
    }
    else if(test != 10) {
        printf("%d-%d%d%d-%d%d%d%d%d-%d",isbn[0],isbn[2],isbn[3],isbn[4],isbn[6],isbn[7],isbn[8],isbn[9],isbn[10],test);
    }
    else {
        printf("%d-%d%d%d-%d%d%d%d%d-X",isbn[0],isbn[2],isbn[3],isbn[4],isbn[6],isbn[7],isbn[8],isbn[9],isbn[10]);
    }
    return 0;
}

虽然很拉,但是能不能看出来,其实就是因为直接读入数字的话,会导致一次读进去一个大于10的整数,所以先读进去字符,再转换


by sduoooh @ 2021-12-24 18:26:00

@G15010709265 对的,已经解决了,谢谢!


|