首先输入最后一位数字有可能是X(罗马数字10),需要特判。
如果所给序列不对输出来的也不是原序列,这句:
```cpp
cout<<word[0]<<"-"<<word[1]<<word[2]<<word[3]<<"-"<<word[4]<<word[5]<<word[6]<<word[7]<<word[8]<<"-"<<word[9];
```
最后应该是end_word,但是输出还需要考虑'X'。 再说一点,你不把样例复制下来放到程序里面验证一下?样例都不过,粘贴的时候点窗口左上角找到编辑->粘贴。
by Terrible @ 2020-02-17 16:59:24
@[Terrible](/user/195942) 10分表示就过了样例;还有就是请问罗马数字X大小是10吗,什么情形下需要考虑X的存在?
by zhuyi3625 @ 2020-02-17 17:19:51
```cpp
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。
```
认真看题,找找ASCII表,在ASCII表中数字'0'~'9'在一块,'a'~'z'在一块,'A'~'Z'在一块,可以看看其对应的数字,但是我们一般在程序中写'X'就代表'X'对应的数字。
```cpp
if(a[i]=='X')
word[j]=10;
else
{
word[j]=a[i]-'0';
++j;
}
```
最后输出的时候需要特判end_word,如果为10,则输出'X'。
by Terrible @ 2020-02-17 17:42:44
样例有两个,样例2你没过。测试点很**坑**另9个测试点几乎都跟X有关,理解题意很重要。
by Terrible @ 2020-02-17 17:48:51
特别附注:身份证最后面一位也可以有11种,0,1,2,3,4,5,6,7,8,9,X,都在ASCII的范畴内,真正的罗马数字是‘Ⅹ’,不在ASCII范畴内,属于**万国码**(Unicode),表示出来需要2字节,汉字也是2字节。一般来说能用ASCII不用Unicode,ASCII规范形成早于Unicode。
by Terrible @ 2020-02-17 17:56:08
@[Terrible](/user/195942) 明白了,感谢耐心的解答
by zhuyi3625 @ 2020-02-19 14:08:39
@[Terrible](/user/195942) 已AC,之前考虑的不够全面,忘了整型和字符型的不同,也没考虑到10;思路还是一个思路,不过只是实现了计算,优化方面有点吃力
by zhuyi3625 @ 2020-02-19 15:05:00
@[Terrible](/user/195942)
```
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char a[14];
int word[10];
char end_number;
int j=0;//存储数字用的序号
int i,sum=0,end_word;
gets(a);
for(i=0;i<13;++i)//提取数字
{
if(a[i]=='-')
{
continue;
}
else//a[i]不是分隔符情况下
{
word[j]=a[i]-'0';
if(a[i]=='X')
{
word[9]=10;
continue;
}
++j;
}
}
//此时有10个j,最大为j[9]
for(i=0;i<9;++i)
{
sum+=word[i]*(i+1);//求和
}
end_word=sum%11;//此时所有数据计算完毕
//需要将整形转化为字符型进行输出
if(word[9]==end_word)
{
cout<<"Right";
}
else if(end_word==10)
{
end_number='X';
cout<<word[0]<<"-"<<word[1]<<word[2]<<word[3]<<"-"<<word[4]<<word[5]<<word[6]<<word[7]<<word[8]<<"-"<<end_number;
}
else
{
cout<<word[0]<<"-"<<word[1]<<word[2]<<word[3]<<"-"<<word[4]<<word[5]<<word[6]<<word[7]<<word[8]<<"-"<<end_word;
}
return 0;
}
by zhuyi3625 @ 2020-02-19 15:08:41
@[zhuyi3625](/user/314719)
我写了地比较密集,不过思路上更简洁了。
```cpp
#include<cstdio>
int main()
{
char c[15],end;
int i,j,sum=0;
scanf("%s",c);
for(i=0,j=1;i<11;i++)
if(c[i]!='-')
sum+=(j++)*(c[i]-'0');
sum%=11;
end=(sum==10)?'X':sum+'0';
if(end==c[12])
printf("Right");
else
{
for(i=0;i<12;i++)
putchar(c[i]);
putchar(end);
}
}
```
###### 书写上:
我一般不用多余的{ }行数就能减少。
```cpp
if(判断表达式)
语句;
if(判断表达式)
{
n个语句;
}
//这两种形式是等价的,不过花括号之间可以有好多个并列语句。
```
###### 思路上:
①录入字符串。②扫描一遍字符串,不过最后两个字符这个时候不用管,如果不是'-'那么这个字符就是数字,j从1到9遇到数字就+1,把数字(转化成int型)和j相乘,得出sum。③然后让end表示算出的最后一个字符。这样我们就不必考虑'-'的位置了。
```cpp
end=(sum==10)?'X':sum+'0';
//d1?d2:d3 是三目表达式
//如果d1取非零的数(为真),那么表达式返回d2
//如果d1取零(为假),那么表达式返回d3
//它等价于:
if(sum==10)
end='X';
else
end=sum+'0';
```
④此时最后的字符已经算出来了,我们与原来的对比。最后输出。此时也不必考虑'-'的位置。
by Terrible @ 2020-02-19 17:59:09
@[Terrible](/user/195942) 学习了,这个三目运算符有点闪眼睛
by zhuyi3625 @ 2020-02-20 14:47:30