C語言程序設計100例之(80):ISBN 號碼


例80   ISBN 號碼

問題描述

每一本正式出版的圖書都有一個ISBN號碼與之對應,ISBN碼包括9位數字、1位識別碼和3位分隔符,其規定格式如x-xxx-xxxxx-x,其中符號-就是分隔符(鍵盤上的減號),最后一位是識別碼,例如0-670-82162-4就是一個標准的ISBN碼。ISBN碼的首位數字表示書籍的出版語言,例如0代表英語;第一個分隔符-之后的三位數字代表出版社,例如670代表維京出版社;第二個分隔符后的五位數字代表該書在該出版社的編號;最后一位為識別碼。

識別碼的計算方法如下:

首位數字乘以1加上次位數字乘以2……以此類推,用所得的結果mod11,所得的余數即為識別碼,如果余數為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號碼(包括分隔符-)。

輸入樣例

0-670-82162-0

輸出樣例

0-670-82162-4

        (1)編程思路。

        簡單的字符串模擬題。用循環對字符串中的前11個字符進行處理,計算出識別碼與最后一個字符比較,根據比較結果輸出相應信息。

        (2)源程序。
#include <stdio.h>
int main()
{
    char isbn[14],ch;
    int i,k,s;
    scanf("%s",isbn);
    for (i=0,k=0,s=0;i<=10;i++)
        if (isbn[i]!='-')
        {
           k++;
           s+=k*(isbn[i]-'0');
        }
    if (s%11==10)  ch='X';
    else  ch=(s%11)+'0';
    if (isbn[12]==ch) printf("Right\n");
    else { isbn[12]=ch; printf("%s\n",isbn); }
    return 0;
}

        將此源程序提交給洛谷OJ題庫 P1055 ISBN 號碼(https://www.luogu.com.cn/problem/P1055)可以Accepted。

習題80

80-1  信用卡號的驗證

問題描述

當你輸入信用卡號碼的時候,有沒有擔心輸錯了而造成損失呢?其實可以不必這么擔心,因為並不是一個隨便的信用卡號碼都是合法的,它必須通過Luhn算法來驗證通過。

該校驗的過程:

1、從卡號最后一位數字開始,逆向將奇數位(1、3、5等等)相加。

2、從卡號最后一位數字開始,逆向將偶數位數字,先乘以2(如果乘積為兩位數,則將其減去9),再求和。

3、將奇數位總和加上偶數位總和,結果應該可以被10整除。

例如,卡號是:5432123456788881

則奇數位和=35

偶數位乘以2(有些要減去9)的結果:1 6 2 6 1 5 7 7,求和=35。

最后35+35=70 可以被10整除,認定校驗通過。

請編寫一個程序,從鍵盤輸入卡號,然后判斷是否校驗通過。通過顯示:“Right”,否則顯示“Wrong”。

輸入

一串信用卡號。

輸出

判斷結果。

輸入樣例

356827027232780

輸出樣例

成功

       (1)編程思路。

        簡單的字符串模擬題,用循環對字符串按題目要求進行處理。

       (2)源程序。

#include <stdio.h>
#include <string.h>
int main()
{
    char s[26];
    scanf("%s",s);
    int sum=0,t;
    int i,f;
    for (i=strlen(s)-1,f=1;i>=0;i--,f=1-f)
    {
        if (f==1)
            sum+=s[i]-'0';
        else
        {
            t=2*(s[i]-'0');
            if (t>9) t-=9;
            sum+=t;
        }
    }
    if (sum%10==0) printf("Right\n");
    else  printf("Wrong\n");
    return 0;
}
80-2  寶石串

問題描述

有一種寶石串,由綠寶石和紅寶石串成,僅當綠寶石和紅寶石數目相同的時候,寶石串才最為穩定,不易斷裂。安安想知道從給定的寶石串中,可以截取一段最長的穩定的寶石串,有多少顆寶石組成。請你幫助他。

綠寶石用‘G’表示,紅寶石用‘R'表示。

輸入

一行由G和R組成的字符串

輸出

最長的穩定的寶石串有多少顆寶石組成

輸入樣例

GRGGRG

輸出樣例

4

        (1)編程思路。

        定義兩個數組int a[1000001],b[1000001];,其中a[i]和b[i]分別表示前一個寶石中綠寶石和紅寶石的個數,初始值全部為0。

        用循環對寶石串進行掃描處理,計算出數組a和b各元素的值。

        之后對區間[i,j](區間左端點從1~n,n為寶石串中寶石的個數;右端點從n~i)進行處理,若在某段區間中,綠寶石的個數a[j]-a[i-1]和紅寶石的個數b[j]-b[i-1]相等,則這段區間中的寶石可以構成穩定的寶石串,窮舉找到最長的區間即可。

        (2)源程序。

#include <stdio.h>
int a[1000001],b[1000001];
int main()
{
    char str[1000001];
    scanf("%s",str);
    a[0]=b[0]=0;
    int i,j;
    for (i=1;str[i-1]!='\0';i++)
    {
       if (str[i-1]=='G')
       {
           a[i]=a[i-1]+1;
           b[i]=b[i-1];
       }
       else
       {
           b[i]=b[i-1]+1;
           a[i]=a[i-1];
       }
    }
    int n=i-1;
    if (a[n]==0 || b[n]==0)
    {
        printf("0\n");
        return 0;
    }
    int ans=0;
    for (i=1;i<=n;i++)   // 區間左端點
    {
        if (n-i+1<ans) break;
        for (j=n;j>=i;j--)
        {
            if (j-i+1<=ans) break;
            if (a[j]-a[i-1]==b[j]-b[i-1])
              if (ans<j-i+1) ans=j-i+1;
        }
    }
    printf("%d\n",ans);
    return 0;
}

        將此源程序提交給洛谷OJ題庫 P2697 寶石串(https://www.luogu.com.cn/problem/P2697)可以Accepted。

80-3  方便記憶的電話號碼

問題描述

英文字母(除Q和Z外)和電話號碼存在着對應關系,如下所示:

A,B,C -> 2

D,E,F -> 3

G,H,I -> 4

J,K,L -> 5

M,N,O -> 6

P,R,S -> 7

T,U,V -> 8

W,X,Y -> 9

標准的電話號碼格式是xxx-xxxx,其中x表示0-9中的一個數字。有時為了方便記憶電話號碼,我們會將電話號碼的數字轉變為英文字母,如把263-7422記成America。有時,我們還加上“-”作為分隔符,如把449-6753記成Hi-World。當然,我們未必要將所有的數字都轉變為字母,比如474-6635可以記成iPhone-5。

總之,一個方便記憶的電話號碼由數字和除Q、Z外的英文字母組成,並且可以在任意位置插入任意多的“-”符號。

現在 ,我們有一個列表,記錄着許多方便記憶的電話號碼。不同的方便記憶的電話號碼可能對應相同的標准號碼,你的任務就是找出它們。

輸入

第一行是一個正整數n(n <= 100000),表示列表中的電話號碼數。

其后n行,每行是一個方便記憶的電話號碼,它由數字和除Q、Z外的英文字母、“-”符號組成,其中數字和字母的總數一定為7,字符串總長度不超過200。

輸出

輸出包括若干行,每行包括一個標准電話號碼(xxx-xxxx)以及它重復出現的次數k(k >= 2),中間用空格分隔。輸出的標准電話號碼需按照升序排序。

如果沒有重復出現的標准電話號碼,則輸出一行“No duplicates.”。

輸入樣例

12

4873279

ITS-EASY

888-4567

3-10-10-10

888-GLOP

TUT-GLOP

967-11-11

310-GINO

F101010

888-1200

-4-8-7-3-2-7-9-

487-3279

輸出樣例

310-1010 2

487-3279 4

888-4567 3

         (1)編程思路。

        編寫函數int ctoi(char ch),按英文字母(除Q和Z外)和電話號碼存在的對應關系,把字符ch轉換為對應的數字。

        輸入時將所有的電話號碼全部轉換為全部由7位數字表示的電話號碼后進行保存,去掉輸入中的連接符“-”,將字母全部轉換為對應的數字。

        將保存好的電話號碼按整數從小到大排列,這樣相同的號碼一定會排列在一起,用循環對排序好的數組進行掃描處理,重復次數超過2的電話號碼按要求格式輸出。

        (2)源程序。

#include <stdio.h>
#include <algorithm>
using namespace std;
int ctoi(char ch)      // 把字符ch轉換為對應的數字
{
    if(ch=='A' || ch=='B' || ch=='C')
        return 2;
    if(ch=='D' || ch=='E' || ch=='F')
        return 3;
    if(ch=='G' || ch=='H' || ch=='I')
        return 4;
    if(ch=='J' || ch=='K' || ch=='L')
        return 5;
    if(ch=='M' || ch=='N' || ch=='O')
        return 6;
    if(ch=='P' || ch=='R' || ch=='S')
        return 7;
    if(ch=='T' || ch=='U' || ch=='V')
        return 8;
    if(ch=='W' || ch=='X' || ch=='Y')
        return 9;
    if (ch>='0' && ch<='9')
        return ch-'0';
}
int main()
{
    int n;             //號碼數
    scanf("%d",&n);
    int out[100001];   // 存放待輸出的電話號碼
    int num,i,j;
    for(i=0;i<n;i++)
    {
        num=0;
        char s[201];
        scanf("%s",s);
        for (j=0;s[j]!='\0';j++)
        {
            if(s[j]=='-' || s[j]=='Q' || s[j]=='Z')
                continue;
            num=num*10+ctoi(s[j]);
        }
        out[i]=num;
    }
    sort(out,out+n);
    int flag=1;        // 標記是否所有號碼都是唯一的
    i=0;
    while (i<n)
    {
        int times=0;       //  out[i]出現的次數
        int k=out[i];
        int  sign=0;       // 標記k出現次數是否大於2
         while (i<n && k==out[i])
        {
            times++;
            i++;
            if(times==2)
            {
                flag=0;
                sign=1;
            }
        }
        if (sign)
        {
            printf("%03d-%04d %d\n",k/10000,k%10000,times);
        }
    }
    if (flag)
        printf("No duplicates.\n");
    return 0;
}

        將此源程序提交給北大OJ題庫 POJ 1002 487-3279(http://poj.org/problem?id=1002)可以Accepted。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM