文章目录
玩数字
请注意,数字123456789是一个9位数,正好包含从1到9的数字,没有重复。加倍,我们将得到246913578,正好是另一个9位数,正好是从1到9的数字,只是在一个不同的排列中。检查看看结果,如果我们再次翻倍!
现在,您应该检查这个属性是否有更多的数字。也就是说,将给定的数字加倍k数字,您将知道产生的数字是否仅由原始数字中的数字排列组成。
输入规格:
每个输入包含一个测试用例。每个大小写包含一个不超过20位数的正整数。
输出规格:
对于每个测试用例,首先在一行“是”中打印“是”,如果输入数字加倍,则给出一个数字,该数字仅由原始数字中的数字排列组成,如果不是,则为“否”。然后在下一行,打印加倍的数字。
样本输入:
1234567899
样本输出:
Yes
2469135798
思路分析
1.接收数据 char str[]
2.从最低位往最高位,先将 str[] 中每个字符转换为整数 temp(temp 作为数组 num[] 的下标),再将 temp 出现的次数记在 num[] 中, 然后再判断加倍后的 temp 会不会大于 9,大于 9 的话要让下一位进 1,加倍后的 temp 出现的次数在 num[] 中再减掉,这样步骤 3 判断 num[] 中是否都为 0 就可以知道是否由原始数字中的数字排列组成
3.输出结果,先判断是否首位要进一,再判断 num[] 中是否都为 0
代码
#include <stdio.h>
#include <string.h>
int main(){
//1.接收数据 char str[], strNew[] 则用来存加倍后的字符串
// ? 数组长度为22: 最长为20,但要加上字符串数组最后一位存的 '\0' ,而且加倍后有可能首位会进一
char str[21], strNew[22] = "";
gets(str);
/*
2. ? 从最低位往最高位,先将字符型转换为整数型 temp(temp 作为数组 num[] 的下标),再将 temp 出现的次数记在 num[] 中, 然后 再判断加倍后的 temp 会不会大于 9,大于 9 的话要让下一位进 1,加倍后的 temp 出现的次数在 num[] 中再减掉
*/
int num[10] = {0,0,0,0,0,0,0,0,0,0};//下标 0 ~ 9 的 num[] 中元素一开始均为 0
int len = strlen(str), temp, flag = 0;//flag 用来记加倍后是否进位
for(int i = len - 1; i >= 0; i--){
temp = str[i] - '0';//将 str[] 中每个字符转换为整数 temp
num[temp]++;//对应下标加一
if(temp < 5){
strNew[i] = (char)(temp * 2 + flag + '0');//将整数型转换为字符型存在 strNew[] 中
num[temp * 2 + flag]--;//对应下标
flag = 0;//下一位不用进一
}else{
strNew[i] = (char)((temp * 2) % 10 + flag + '0');
num[(temp * 2) % 10 + flag]--;
flag = 1;//下一位进一
}
}
//3. ? 输出结果,先判断是否首位要进一,再判断 num[] 中是否都为 0
if(flag == 1){//判断是否首位要进一
printf("%s\n%c%s","No",'1',strNew);
}else{
for(int j = 0; j < 10; j++){//判断 num[] 中是否都为 0
if(num[j] != 0){
printf("%s\n%s","No",strNew);
break;
}
if(j == 9){
printf("%s\n%s","Yes",strNew);
}
}
}
}
错因分析
错误: 输出时末尾出现乱码
原因: 字符串结尾并没有结尾符’\0’
措施: 可以在 strNew[] 赋值末尾赋上 ‘\0’ 或者初始化 strNew[] = “”;
知识点
gets 函数读入一行字符串时,会在最末尾自动加上’\0’结尾
模板
1.在字符串数组 str[] 末尾赋上 ‘\0’
方法一: 赋完值后直接 str[i] = '\0';
方法二: 初始化时 str[20] = "";
2. 整数型与字符型互换
整数型 --> 字符型: strNew[i] = (char)(temp * 2 + flag + '0');
字符型 --> 整数型: temp = str[i] - '0';
3. 对照两串长度不超过 20 位的数出现的数字是否一样,如 12234 与 23241 则一样
分析: int, long, unsigned int, unsigned long 最多存 10 位的数(不包括所有的数), 再长就要用 数组 来存
int num[10] = {0,0,0,0,0,0,0,0,0,0};//下标 0 ~ 9 的 num[] 中元素一开始均为 0
num[temp]++;//对应下标加一
num[temp * 2 + flag]--;//对应下标
for(int j = 0; j < 10; j++){
if(num[j] != 0){
printf("%s\n%s","No",strNew);
break;
}
if(j == 9){
printf("%s\n%s","Yes",strNew);
}
}
4. flag的妙用一
flag 常用于标记,此处用于 if-else 分支处区分走的是哪一条分支