開始刷題,感覺代碼量和基礎太渣了,導致數據結構不會,重頭慢慢刷吧~
1、題目
Sample Input:
1234567899
Sample Output:
Yes
2469135798
譯文:
注意,編號123456789是一個9位數字,由1到9之間的數字組成,沒有重複。加倍我們將得到246913578,這恰好是另一個9位數的數字,由1到9的數字組成,只是排列不同。如果我們再加倍檢查一下結果!
現在您應該檢查這個屬性是否有更多的數字。也就是說,把一個給定的數字乘以兩倍,再加上k個數字,你就可以知道得到的數字是否只由原始數字中的數字排列而成。
輸入規格:
每個輸入包含一個測試用例。每個大小寫包含一個不超過20位的正整數。
輸出規格:
對於每一個測試用例,如果輸入的數字加倍,則第一次在“是”行中打印一個數字,該數字僅由原始數字中的數字排列而成,否則爲“否”。然後在下一行中,打印加倍的數字。
2、代碼
#include <stdio.h>
#include <string.h>
int main (){
char start[21];
char end[21];
gets(start); //輸入數
int t,i,j,m=0,s;
t=strlen(start); //存入數的長度即位數
int flag1=1;
//第一位數字大於5要進位,字符運算
if((start[0]-'0')*2>=10){
end[0]='1'; //乘2進位只可能爲1
flag1=0; //位數改變則表明一定不同
}
//從末尾開始做乘法
for(i=t-1; i>=0; i--){
//有進位
if((start[i]-'0')*2>=10){
s=(start[i]-'0')*2%10+m;
end[i+1]='0'+s;
m=1; //進位存儲
}
//無進位
else{
s=(start[i]-'0')*2+m;
end[i+1]='0'+s;
m=0;
}
}
int flag=1;
//在end數組中遍歷,若存在兩數相等,則在start數組中將此數變爲a
for(i=1; i<=t; i++){
for(j=0; j<t; j++){
if(end[i]==start[j]){
start[j]='a';
break;
}
}
}
//若start數組中不全爲a,則證明有不同的數產生
for(i=0; i<t; i++){
if(start[i]!='a'){
flag=0;
break;
}
}
if(flag==1)
printf("Yes\n");
else
printf("No\n");
if(flag1==0){
//進位後輸出從第一位開始
for(i=0; i<=t; i++){
printf("%c",end[i]);
}
}
else{
//無進位從第二位開始
for(i=1; i<=t; i++){
printf("%c",end[i]);
}
}
return 0;
}
3、討論
這個題,由於限制是不超過20位的數字,若採用整形會造成越界問題,別問我怎麼知道的,試出來的,哈哈,所以採用字符數組來存儲大數並模擬大數的乘2運算。
由於只是乘2運算,進位不是那麼複雜,可以只在存儲數組前空出一位方便進位即可。
先保存最開始的第一位進位,然後正常計算,如果乘2之後大於等於10,那麼進1,否則,不進。
妙啊!!!