lalalala


私信TA

用户名:zhangshuo

访问量:161495

签 名:

像狗一样的学习,像绅士一样地玩耍。

等  级
排  名 7
经  验 31295
参赛次数 10
文章发表 201
年  龄 12
在职情况 学生
学  校 芜湖市第十一中学
专  业

  自我简介:

今日懒惰流下的口水,将会成为明日里伤心的泪水。

解题思路:





注意事项:





参考代码:

几种解法不同的代码:

1.不需动脑的王牌代码,不需要字符串的对于初学者来说非常实用的一段代码。

#include<iostream>
    #include<cstdio>
    using namespace std;    int main(){        int a[5],first,second,third,fourth,fifth,sum=0;        cin>>a[1];
        getchar();        cin>>a[2];
        getchar();        cin>>a[3];
        getchar();        if(scanf("%d",&a[4])!=1)a[4]=10;
        sum+=a[1];
        first=a[2]/100;
        second=(a[2]/10)%10;
        third=a[2]%10;
        sum=sum+first*2+second*3+third*4;
        first=a[3]/10000;
        second=(a[3]/1000)%10;
        third=(a[3]/100)%10;
        fourth=(a[3]/10)%10;
        fifth=a[3]%10;
        sum=sum+first*5+second*6+third*7+fourth*8+fifth*9;
        sum=sum%11;        if(sum==a[4])cout<<"Right";        else{ if(sum!=10)printf("%d-%d-%d-%d",a[1],a[2],a[3],sum);                else printf("%d-%d-%d-X",a[1],a[2],a[3]);
        }        return 0;
    }

这个代码虽然有点繁琐,但确实能够AC。但是,一位大佬提出了一个问题:cin和getchar不能连用。本蒟蒻确实不知道。然后,作为一个字符串渣渣,我忽然想到了一种解决方式:在c++中,scanf有一个神奇的功能:可以跳过一些字符。 例如:scanf("%d,%d",&a,&b);,当输入1,2时,scanf跳过了“,”,把1赋给a,把2赋给b。现在,我们可以这样读入: scanf("%d-%d-%d-",&a[1],&a[2],&a[3]);这样,我们不利用getchar来读无用的“-”,而使用scanf的特性。这就是一个字符串蒟蒻的代码。
对于新手来说,还有一点小小的问题:if(scanf("%d",&a[4])!=1)a[4]=10;是什么意思?
实际上,当最后一位为x也就是字符时,把x赋给a[4]将不会成功。若赋值成功,scanf函数将会有一个返回值:1。所以,可以利用这个来判断是否是x,达到赋值的效果。
接下来便是一些取各位数字的方法,无需说明。

2.简单直白迅速的暴利模拟。

#include<iostream>
#include<cstdio>
using namespace std;
char a[14],b[14],t1,t2;int t22=0;
int main()
{
//    freopen("isbn.in","r",stdin);
//    freopen("isbn.ans","w",stdout);
    scanf("%c-%c%c%c-%c%c%c%c%c-%c",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9],&t1);//暴力读入//注意,利用了scanf的特性,可以读入指定的字符,具体可以自己查找资料。因此读入的都是有用字符
    for(int i=1;i<=9;++i)
        t22+=(a[i]-'0')*i;//暴力地安题目要求把有用的自负处理求和
    t2=t22%11+'0';//求出末位的标准值
    if(t2=='0'+10)t2='X';//特殊处理
    if(t1==t2)//判断,如果符合,输出Right
    {        cout<<"Right";        return 0;
    }    cout<<a[1]<<'-'<<a[2]<<a[3]<<a[4]<<'-'<<a[5]<<a[6]<<a[7]<<a[8]<<a[9]<<'-'<<t2;//暴力地输出
    return 0;//程序完美结束}

3.集合众多优点最为实用的代码之一,闪亮登场。

#include<iostream>
#include<string>
using namespace std;int main()
{    string isbncode;    
     int mathcode[13]={0},realcode=0;    
     long int mycode=0;    
     cin>>isbncode;//输入ISBN号 
    for(int i=0;i<=12;i++)//转换为数字 
        {
             mathcode[i]=isbncode[i]-'0'; //字符转换为数字 
        }
        mycode=mathcode[0]*1+mathcode[2]*2+mathcode[3]*3+mathcode[4]*4+mathcode[6]*5+mathcode[7]*6+mathcode[8]*7+mathcode[9]*8+mathcode[10]*9;
        mycode=mycode%11;//求出正确的识别码 
        if (mycode==10)
        {
            mycode='X'-'0';
        } 
        if(mycode==mathcode[12])//如果正确 
           cout<<"Right";//注意第一个字母大写,和题目要求一致 
        else
        {           //用一一对应的方式输出 
           cout<<mathcode[0]<<'-'
           <<mathcode[2]<<mathcode[3]<<mathcode[4]<<'-'
           <<mathcode[6]<<mathcode[7]<<mathcode[8]<<mathcode[9]<<mathcode[10]
           <<'-'<<char(mycode+'0');//用char函数强制转换为字符类型 
        }    return 0;
}

4.稍慢却好理解一些的一道直接模拟。

#include<iostream>
using namespace std;
int ans=0,k=1,check;char isbn[14]; //存ISBN码void get_in(){ //用来输入
    for(int i=1;i<=12;i++){    cin>>isbn[i];    if(isbn[i]!='-'){ //注意考虑-的情况
        ans+=(isbn[i]-'0')*k; //直接加起来
        k++; //用来累加的计数器
        }
    }    cin>>isbn[13];    if(isbn[13]!='X'){ //X单独处理
            check=isbn[13]-'0';
    }else check=10;
}void put(){ //输出函数
    if(ans%11==check){        cout<<"Right";
    }else{    
        for(int i=1;i<=12;i++) cout<<isbn[i];        if(ans%11!=10) cout<<ans%11; else cout<<"X"; //X单独处理
    }
}int main(){ //优雅的主程序
    get_in();
    put();    return 0;
}

5.较为常见的转换方法。

#include<iostream>
#include<cstring>
using namespace std;//头文件
int main(){    char s[20]; //isbn号码需要使用的字符串
    int i,ans=0,sum=0;    cin>>s;//输入isbn号码
    for(i=0;i<=11;i++){        if(s[i]>=48&&s[i]<=57){
            sum++;//数字的位数
            ans+=sum*(s[i]-48);//累乘计算mod前的值
        }        else continue;//遇到“-”不处理
    }
    ans%=11;//mod11得到isbn的识别码
    ans+=48;//转换为ASCII码
    if(ans==58)  ans='X';//处理“X”
    if(ans==s[12])  cout<<"Right"<<endl;//判断是否正确
    else {
      s[12]=ans;//将正确的值赋给最后一位
      for(i=0;i<=12;i++)  cout<<s[i];//输出正确的值
      cout<<endl;
    }    return 0;
}

6.和上面一种解法形成一个鲜明的对比,这是一种极其奇葩的解法。

#include<cstdio>
#include<cstring>//上面两个头文件不需要解释吧using namespace std;int main(){    char every[13];int sum=0,k=1;         //一个数组存数据,一个用来累加和,一个用来计算多少加了次(切记不能用i)
    for(int i=0;i<13;i++){
        every[i]=getchar();                       //读入数据
        if(every[i]!='-'&&i!=12) sum+=(every[i]-'0')*k++;         //进行判断:如果不是最后一个且不是分隔符'-'就累加
    }
    sum%=11;                            //所谓Mod 11的过程
    int tmp=every[12];                 //先保护之前的ISBN号
    every[12]=sum==10?'X':sum+'0';                     //写一个三目,判断是不是'X'也就是10
    if(tmp==every[12]) printf("Right");                   //如果不变,说明原来就是对的,输出"Right"
    else for(int i=0;i<13;i++){                                 //否则遍历一次数组全部输出来
        printf("%c",every[i]);
    }    return 0;                 //返回:0}

6.不服者来战,史上最简短的代码之一。

#include<stdio.h>
int main(void){  char a[14], mod[12] = "0123456789X"; //先将mod11后的十一个字符存入数组
  gets(a); //输入字符串
  int i, j = 1, t = 0;  for(i = 0; i < 12; i++) {        if(a[i] == '-') continue; //字符串为分隔符‘-’时跳过此次循环进入下一次循环
    t += (a[i]-'0')*j++; //t储存 第j个  数字  * j 的和
  }  if(mod[t%11] == a[12]) printf("Right");  else {
      a[12] = mod[t%11]; //若识别码错误,则赋正确的识别码,然后输出
      puts(a);
  }  return 0;
}

想啊想,怎么觉得的noi也就那样呢!也别怪我讽刺一下这个noi难度题!
对了,也别煞费了我的一番苦心,点个赞呗!!!!


 

0.0分

2 人评分

  评论区

学到了,大佬喝可乐!
2019-10-26 20:41:49
  • «
  • 1
  • »