翎马 2022-10-27 17:23
浏览 30
已结题

PAT 乙级 1031 第二个测试点 sscanf做法

PAT 乙级 1031 查身份证 第二个测试点
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:

首先对前17位数字加权求和 权重分配为:{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:

Z0 1 2 3 4 5 6 7 8 9 10
M1 0 X 9 8 7 6 5 4 3 2
输入格式:

输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。

输出格式:

按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理 只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常 则输出All passed。

输入样例1:
4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X
输出样例1:
12010X198901011234
110108196711301866
37070419881216001X
输入样例2:
2
320124198808240056
110108196711301862
输出样例2:
All passed
我的做法↓
#include <stdio.h>
int main(){
    int N;
    scanf("%d", &N);
    getchar();
    int j, p, i = 0;
    int tag2=0;
    int p1;
    int tag; //追杀X 
//    int quan[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    int sum = 0;
    int z;
    int m[11] = {1, 0, 88, 9, 8, 7, 6, 5, 4, 3, 2};
    char ch[20];
    char ch_1[N][20];
    char seek;
    int Q = 0; 
    int num[N][18];
    for(j=0; j<N; j++){
        tag = 0;
        for(p=0; p<18; p++){    
            ch[p] = getchar();
            if(ch[p]>57 || ch[p]<48){   //asii
                tag++; 
            }
        }
        getchar();
        if(tag!=0){
            for(p1=0; p1<=17; p1++){
                ch_1[Q][p1] = ch[p1];
                printf("%c", ch_1[Q][p1]);    
            }
            printf("\n");
            Q++;
            continue;
        }
        if(ch[17]<=57 && ch[17]>=48)
            sscanf(ch, "%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", &num[i][0], &num[i][1], &num[i][2], &num[i][3], &num[i][4], &num[i][5], &num[i][6], &num[i][7], &num[i][8], &num[i][9], &num[i][10], &num[i][11], &num[i][12], &num[i][13], &num[i][14], &num[i][15], &num[i][16], &num[i][17] );
        else{
            sscanf(ch, "%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%c", &num[i][0], &num[i][1], &num[i][2], &num[i][3], &num[i][4], &num[i][5], &num[i][6], &num[i][7], &num[i][8], &num[i][9], &num[i][10], &num[i][11], &num[i][12], &num[i][13], &num[i][14], &num[i][15], &num[i][16], &seek);
            num[i][17] = (int)(seek);
        }
        //{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        sum = 7*num[i][0] + 9*num[i][1] + 10*num[i][2] + 5*num[i][3] + 8*num[i][4] + 4*num[i][5] + 2*num[i][6] + 1*num[i][7] + 6*num[i][8] + 3*num[i][9] + 7*num[i][10] + 9*num[i][11] + 10*num[i][12] + 5*num[i][13] + 8*num[i][14] + 4*num[i][15] + 2*num[i][16]; 
        z = sum % 11;
        if(m[z]!=num[i][17]){
            for(int K=0; K<18; K++){
                if(num[i][K]<=9&&num[i][K]>=0)
                    printf("%d", num[i][K]);
                else if(num[i][K]!=88)
                    printf("%c", seek);
                else if(num[i][K]==88)
                    printf("X");
            }
            printf("\n");
            tag2++;
        }
        sum = 0;
        i++;
    }
    if(Q==0&&tag2==0){
        printf("All passed");
    }
    
    return 0;
}

测试点2一直过不去。
改的时候以为错误点是“不只是会输入X”(还会输入AB之类的) 然后就改成ascii码,好像也不对。尝试了X在最后的例子 也是可以all passed. TwT。
解题思路比较朴实:【全输入验证前17,不是的输出,是的,验证18位】 。看了网上的,好像有c++混合的比较多,感觉思路也是差不多,实在是看不出错哪了 ORZ。
  • 写回答

1条回答 默认 最新

  • 翎马 2022-10-28 14:39
    关注

    我找到哪错了,好像就是最后一个X的问题,我改着改着又改回去了。。。
    xdm测试点2错的,可以输入↓,试试

    1
    11111112111111111X
    

    附:在23行处改为

    if(p<17){
                    if(ch[p]>57 || ch[p]<48){
                        tag++; 
                    }
    
    评论

报告相同问题?

问题事件

  • 系统已结题 11月5日
  • 赞助了问题酬金1元 10月28日
  • 修改了问题 10月28日
  • 创建了问题 10月27日

悬赏问题

  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作