首页 > 试题广场 >

[NOIP2008]ISBN号码

[编程题][NOIP2008]ISBN号码
  • 热度指数:24618 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 50M,其他语言100M
  • 算法知识视频讲解
每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。
你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。


输入描述:
只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。


输出描述:
共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。
示例1

输入

0-670-82162-4

输出

Right
示例2

输入

0-670-82162-0

输出

0-670-82162-4
可以写得更简洁,但不想在这种题上改了。X搞得有点烦了
#include <stdio.h>

//计算权重
//x为需要计算的数,n表示当前阶段的权重
int Calc(int x, int n)
{
    if (x <= 0)
    {
        return 0;
    }

    return Calc(x / 10, n - 1) + x % 10 * n;
}

int main()
{
    int i = 0;
    int s = 0;
    int b = 0;
    char n = 0;
    int rightN = 0;

    scanf("%d-%d-%d-%c", &i, &s, &b, &n);

    rightN = (Calc(i, 1) + Calc(s, 4) + Calc(b, 9)) % 11;

    if(n == 'X' || n == 'x')
    {
        n = '0' + 10;
    }

    if (rightN == n - '0')
    {
        printf("Right\n");
    }
    else if(rightN == 10)
    {
        printf("%d-%d-%d-X\n", i, s, b);
    }
    else
    {
        printf("%d-%d-%d-%d", i, s, b, rightN);
    }

    return 0;
}


编辑于 2024-03-29 18:46:15 回复(0)
#include <stdio.h>

int main() {
  int language, pub, num,id, result=0, n=1, pub1, num1;
  char ch;
  scanf("%d-%d-%d-%c", &language, &pub, &num, &ch);
  if(ch=='X'){
    id =10;
  }else {
    id = (int)ch -48;
  }
  pub1= pub;
  num1 = num;
  int a[9];
  // 数据拆分
  a[0] = language;
  for (int i = 3 ; i >= 1; i--) {
    a[i] = pub1 % 10;
    pub1 /= 10;
  }
  for (int i = 8 ; i >= 4; i--) {
    a[i] = num1 % 10;
    num1 /= 10;
  }
  for (int i = 0 ; i < 9; i++) {
    result += a[i] * n;
    n++;
  }
  result = result%11;
  if(result==id){
    printf("Right");
  }else if(result==10){
     printf("%d-%d-%d-X", language, pub, num);
  }else {
      printf("%d-%d-%d-%d", language, pub, num, result);
  }

  return 0;
}
编辑于 2024-02-24 14:32:10 回复(0)
一个for一个if搞定
#include <stdio.h>
int main() {
    char arr[14];
    int i, arr2[14] = { 1, 0, 2, 3, 4, 0, 5, 6, 7, 8, 9 };
    int sum = 0;
    scanf("%s", arr);
    for (i = 0; i < 11; i++) {
        sum += (arr[i] - '0') * arr2[i];
    }
    if ((arr[12] == 'X' ? 10 : arr[12] - '0') != sum % 11) {
        arr[12] = sum % 11 == 10 ? 'X' : sum % 11 + '0';
        printf("%s", arr);
    } else
        printf("Right");
    return 0;
}


发表于 2024-02-20 17:49:37 回复(1)
主要是把题目中这几个需要判断的地方梳理清楚
#include <stdio.h>
#include <stdint.h>
int main() {
    char AingleLetter[13] = {0}; //定义一个数组用来存放获取的数字
    int8_t i = 0;
    int8_t n = 1;
    int sum = 0;//用来存放求和
    int8_t md = 0;//用来存放求得的余数
    int LastCharacter;
    /*该循环把前12个字符和数字存入数组中*/
    for (i = 0; i <= 11; i++) {
        AingleLetter[i] = getchar();
        /*该判断把其中的数字按规则进行了求和*/
        if (AingleLetter[i] >= '0' && AingleLetter[i] <= '9') {
            sum = sum + n * (AingleLetter[i] - '0');//因为前面定义的字符类型,所以在转的过程中要减去'0'
            n++;
        }
    }
    md = sum % 11;
    AingleLetter[12] = getchar();//存入最后一个数字到数组
    /*该判断用来判断是否最后一个值是X*/
    if (AingleLetter[12] == 'X') {
       
        if (md == 10) {
            printf("Right");
        } else {
            AingleLetter[12] = '0' + md;
            /*判断完成,用循环输出*/
            for (int m = 0; m <= 12; m++ ) {
                printf("%c", AingleLetter[m]);
            }
        }
    } else {
        if (AingleLetter[12] == '0' + md) {
            printf("Right");
        } else {
            AingleLetter[12] = '0' + md;
            /*这里要对得到的余数进行判断,如果是10就要把最后一个转换为X,再输出*/
            if (md != 10) {
                /*判断完成,用循环输出*/
                for (int m = 0; m <= 12; m++ ) {
                    printf("%c", AingleLetter[m]);
                }
            } else {
                AingleLetter[12]='X';
                /*判断完成,用循环输出*/
                for (int m = 0; m <= 12; m++ ) {
                    printf("%c", AingleLetter[m]);
                }
            }
        }
    }
    return 0;
}

发表于 2024-02-02 10:21:54 回复(0)
#include <stdio.h>

int main() {
    char a[15] = {0};
    int sum;
    scanf("%s", a);
    sum = (a[0] - 48) * 1 + (a[2] - 48) * 2 + (a[3] - 48) * 3 + (a[4] - 48) * 4 +
          (a[6] - 48) * 5 + (a[7] - 48) * 6 + (a[8] - 48) * 7 + (a[9] - 48) * 8 +
          (a[10] - 48) * 9;
    sum = sum % 11;
    if (a[12] == 'X' && sum == 10) {
        printf("Right");
    } else if (sum == (a[12] - 48)) {
        printf("Right");
    } else {
        for (int i = 0; i <= 11; i++) {
            printf("%c", a[i]);
        }
        if (sum == 10) {
            printf("X");
        } else {
            printf("%d", sum);
        }
    }
    return 0;
}
发表于 2024-01-19 14:53:37 回复(0)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int function(int a,int i)
{
    return a * i;
}

int c = 0;
int main()
{
    char arr[11] = { 0 };
    for (int i = 1; i <= 10; i++)
    {
        scanf("%c", &arr[i]);
        if (arr[i] == '-')
            {
                i--;
            }
    }
    for (int i = 1; i < 10; i++)
    {
        c += function(arr[i]-48, i);
        
    }
    if (c % 11 == 10 && arr[10] == 'X')
    {
        printf("Right");
    }
    else if (c % 11 == arr[10]-48)
    {
        printf("Right");
    }
    else
    {
        for (int i = 1; i < 10; i++)
        {
            printf("%c", arr[i]);
            if (i == 1||i==4||i==9)
            {
                printf("-");
            }
        }
        if (c % 11 != 10)
        {
            printf("%d", c % 11);
        }
        else
        {
            printf("X");
        }
    }
    return 0;
}
发表于 2023-12-28 13:03:30 回复(1)
#include <stdio.h>

int main() {
    int arr[9]={0};
    char ISBN;
    scanf("%d-%1d%1d%1d-%1d%1d%1d%1d%1d-%c", arr,&arr[1],&arr[2],&arr[3],&arr[4],&arr[5],&arr[6],&arr[7],&arr[8],&ISBN); 
    int sum=0;
    int i=0;
    for(i=0;i<=8;i++)
    {
        sum=sum+(arr[i]*(i+1));
    }
    if((sum%11)==10)
    { 
       if(ISBN=='X')
       {
           printf("Right");
       }
      
       else
        {
            printf("%d-%d%d%d-%d%d%d%d%d-%c",arr[0], arr[1],arr[2],arr[3],arr[4],arr[5],arr[6],arr[7],arr[8],'X');
        }
    }
    else
    {
         if((ISBN-48)==sum%11)
         {
            printf("Right");
         }
         else 
         {
            printf("%d-%d%d%d-%d%d%d%d%d-%d",arr[0], arr[1],arr[2],arr[3],arr[4],arr[5],arr[6],arr[7],arr[8],sum%11);
         }
         
    }
    
    
    
    return 0;
}

发表于 2023-09-12 23:48:22 回复(0)

#include <stdio.h>

int main() {
    char ret[13] = {0};
    int i = 0;
    for(i = 0;i < 13; i++)
    scanf("%c",&ret[i]);

    int sum=0;
    int count = 1;
    for(i = 1;i < 13 ; i++)
    {
        if(ret[i-1] >= '0' && ret[i-1] <= '9')
        {
            sum+=(ret[i-1]-48) * count;
            count++;
        }
    }
   

    if(sum % 11 == (ret[12] - 48) || sum % 11 == 10 && ret[12] == 'X')
       printf("Right\n");
    else
    {
        if(sum % 11 < 10)
        ret[12] = sum % 11 + 48;
        else if(sum % 11 == 10)
        ret[12] = 'X';
        for(i=0;i<13;i++)
        {
            printf("%c",ret[i]);
        }
        printf("\n");
    }

    return 0;
}
发表于 2023-06-28 00:11:12 回复(0)
咋地运行不了

#include <stdio.h>

int main() {
    int a1,a2,a3,a4;
    int shi=0;
    int t;
    scanf("%d-%d-%d-%d",&a1,&a2,&a3,&a4);
    shi=1*a1+4*(a2%10)+3*(a2/10%10)+2*(a2/100%10)+9*(a3%10)+8*(a3/10%10)+7*(a3/100%10)+6*(a3/1000%10)+5*(a3/10000%10);
    t=shi%11;
    if(t==a4){
        printf("Right");
    }else{
        printf("%d-%d-%d-%d",a1,a2,a3,t);
    }
    return 0;
}
发表于 2023-06-09 12:37:42 回复(0)
#include <stdio.h>
//循环看不太懂,还不太熟悉
int main() {
    char a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
    int ret, tmp;
    char e, f, g;
    scanf("%c%c%c%c%c%c%c%c%c%c%c%c%c", &a1, &e, &a2, &a3, &a4, &f, &a5, &a6, &a7,
          &a8, &a9, &g, &a10);
    ret = (a1 - '0') * 1 + (a2 - '0') * 2 + (a3 - '0') * 3 + (a4 - '0') * 4 +
          (a5 - '0') * 5 + (a6 - '0') * 6 + (a7 - '0') * 7 + (a8 - '0') * 8 +
          (a9 - '0') * 9;
    tmp = ret % 11;
    //将数字字符转为数字有两种方法:
    //第一种:用数字字符减去’0’即’1’ - ‘0’(它俩是用ASCII码相减的即49 - 48 = 1)
    //第二种:用数字字符减去48(48是‘0’的ASCII码)即’1’ - 48 = 1
    if (tmp == (a10 - '0') || tmp == (a10 - 78)) //'X'=88,
        printf("Right");
    else if (a10 != 'X' && tmp == 10) {
        printf("%c-%c%c%c-%c%c%c%c%c-X", a1, a2, a3, a4, a5, a6, a7, a8, a9);
    } else
        printf("%c-%c%c%c-%c%c%c%c%c-%d", a1, a2, a3, a4, a5, a6, a7, a8, a9, tmp);
    return 0;
}

发表于 2023-04-17 21:00:09 回复(0)
#include <stdio.h>

char fun(char * input, char * right)
{
	int i = 0;
	//将前12位字符复制到right数组内
	for ( i = 0; i < 12; i++)
	{
		*right++ = *input++;	//最终,两个指针都移动到了最后一个数字处
	}
	int temp = 0;
	right -= 12;	//指针返回到编码的第一个数字的位置
	//计算每位数字和对应数字的乘机的和
	for ( i = 1; i <= 9; i++)
	{
		*right == '-' ? right++ : '0';
		temp += (int)(*right-'0') * i;
		right++;
	}
	right++;	//指针移动到编码的最后一位
	//mod 11
	int num = temp % 11;
	//为right数字最后一位效验码赋值
	if (num == 10)
		*right = 'X';
	else
		*right = (char)(num + '0');
	//判断两个数组是否相同
	if (*right == *input)
		return 'R';
	else
		return *right;
}

int main()
{
	char input[14] = { 0 };	//存储输入的编码
	char right[14] = { 0 };	//存储正确的编码
	scanf("%s", input);
	char ret = fun(input, right);//两个数组传参,判断两个数组是否相同
	if ('R' == ret)
		printf("Right");
	else
		printf("%s", right);
	return 0;
}

发表于 2023-03-19 16:28:19 回复(0)
#include <stdio.h>
int main() {
    int a, b,c,g,e,f;
    char d;
    scanf("%d-%d-%d-%c", &a,&b,&c,&d);
    e=a*1;//第一位*1
    f=b/100;//提取第二位
    e+=f*2;//第二位*2并自加
    f=(b/10)%10;//提取第三位
    e+=f*3;//第三位*3并自加
    f=(b%10);//提取第四位
    e+=f*4;//第四位*4并自加
    f=c/10000;//以此类推
    e+=f*5;
    f=(c/1000)%10;
    e+=f*6;
    f=(c/100)%10;
    e+=f*7;
    f=(c/10)%10;
    e+=f*8;
    f=c%10;
    e+=f*9;
    if (d!='X') {//判断最后一位是否为X注意大小写
    f=d-48;//字符转数字(重复利用f
    }else {
    f=10;//大写X
    }
     if( e%11!=f)//判断最后一位是否正确
     {
        if (e%11==10) {//如果最后一位是数字10 那么最后输出X
        printf("%d-%d-%d-%c\n",a,b,c,'X' );
        }else {
         printf("%d-%d-%d-%d\n",a,b,c,e%11 );
        }
       
     }else {//判断正确
        printf("%s\n", "Right");
     }
       
   
    return 0;
}
用了一个简单粗暴的方法直接算,结构简单,面向过程编程
发表于 2023-03-04 14:44:13 回复(0)
#include <stdio.h>

int main() {
    char i[13] = {0};
    int j = 0;
    int k = 1;
    int sum = 0;
    scanf("%s", i);
    for(j = 0; j < 11; j++)
    {
        if(i[j] == '-')
        {
            continue;
        }
        else
        {
            sum = sum + k * (i[j] - '0');
            k++;
        }
    }
    int x = sum % 11;
    if(x == (i[12] - '0') || (x == 10 && i[12] == 'X'))
    {
        printf("Right");
    }
    else {
        for(j = 0; j < 12; j++)
        {
            printf("%c", i[j]);
        }
        if(x == 10)
        {
            printf("X");
        }
        else {
            printf("%d", x);
        }
    }

    return 0;
}
发表于 2023-02-27 18:51:43 回复(2)
#include <stdio.h>
#define LEN_OF_ARR 13
void getUserStr(char userArr[]);
void strToInt(char charArr[], int intArr[]);
void intTostr(int intArr[], char charArr[]);
void calcCheckCode(int intArr[]);

int main() {
    char userCharArr[LEN_OF_ARR];
    char trueCharArr[LEN_OF_ARR];
    int intArr[LEN_OF_ARR];
    // 收集字符
    getUserStr(userCharArr);
    // 字符转换整数
    strToInt(userCharArr, intArr);
    // 计算识别码
    calcCheckCode(intArr);
    // 整数转新字符数组
    intTostr(intArr, trueCharArr);
    // 比较用户输入字符数组和计算识别码后的字符数组末位
    if (userCharArr[LEN_OF_ARR - 1] == trueCharArr[LEN_OF_ARR - 1]) {
        printf("Right\n");
    } else {
        for (int i = 0; i < LEN_OF_ARR; i++) {
            printf("%c", trueCharArr[i]);
        }
        printf("\n");
    }

    return 0;
}

void getUserStr(char userArr[]) {
    // char userAtr[];
    for (int i = 0; i < LEN_OF_ARR; i++) {
        scanf("%c", &userArr[i]);
    }
    getchar();
}

void strToInt(char userArr[], int intArr[]) {
    for (int i = 0; i < LEN_OF_ARR; i++) {
        // 查ASCII表,看字符数字和整数数字的关系相差48捏[○・`Д´・ ○]
        intArr[i] = userArr[i] - 48;
    }
}

void intTostr(int intArr[], char charArr[]) {
    for (int i = 0; i < LEN_OF_ARR; i++) {
        if (intArr[i] == 10) {
            charArr[i] = 'X';
        } else {
            charArr[i] = intArr[i] + 48;
        }
    }
}

void calcCheckCode(int intArr[]) {
    int tempCheckCode = 0;
    for (int i = 0, j = 1; i < LEN_OF_ARR - 1; i++) {
        // "-"字符ASCII码为45,在strToInt函数中减去48,所以现在为-3
        if (intArr[i] == -3) {
            continue;
        }
        tempCheckCode += intArr[i] * j;
        j++;
    }
    tempCheckCode %= 11;
    intArr[LEN_OF_ARR - 1] = tempCheckCode;
}
发表于 2023-02-17 16:12:40 回复(0)
#include <stdio.h>
int main() {
    char a[13] = { 0 }, n;
    int i, m;
    scanf("%s", a);
    for (i = 0; i <= 10; i++) {
        if (a[i] != '-')
            a[i] -= '0';
    }
    m = (1 * a[0] + 2 * a[2] + 3 * a[3] + 4 * a[4] + 5 * a[6] + 6 * a[7] + 7 * a[8]
         + 8 * a[9] + 9 * a[10]) % 11;
    if (m == 10)
        n = 'X';
    else
        n = m + 48;
    if (n == a[12])
        printf("Right");
    else {
        for (i = 0; i <= 12; i++) {
            if (a[i] != '-')
                a[i] += '0';
        }
        a[12] = n;
        printf("%s", a);
    }
    return 0;
}
发表于 2022-12-20 16:30:48 回复(0)
发表于 2022-12-04 15:34:43 回复(0)
#include <stdio.h>
int main() {
    int ch = 0, i = 0,j=0,sum=0;
    char arr[13];
    while ((ch = getchar()) !='\n') {//多组输入
        arr[i] = ch;
        if (arr[i] != '-'&&i!=12) {
            sum+=((int)arr[i] - '0')* (j + 1);//数字字符转整形数字
            j++;
        }
        i++;
    }
    if(arr[12]=='X'&&sum%11==10)//为x的情况
        printf("Right\n");
    else if (sum % 11 == ((int)arr[12]-'0'))
        printf("Right\n");
    else{
        for (int k = 0; k < 12; k++) {
            printf("%c", arr[k]);
        }
        if(sum%11==10)
        printf("X");
        else
        printf("%d",sum%11);
        printf("\n");
}
}

发表于 2022-10-26 20:11:14 回复(0)