華為優招第三題,前兩道題都比較簡單,在這道題上卡住了。說實話不怪我,華為這道題描述有問題哦。其實不應該是較大的數,和較小的數。是最大的數和最小的數。(我在隨機舉例可能的數字組合上浪費了很多時間!!怒!)
整數之循環節點求和 描述: 任意一個不是用完全相同數字組成的四位數,如果對它們的每位數字重新排序,組成一個較大的數和一個較小的數,然后用較大數減去較小數,差不夠四位數時在前面補零,類推下去,最后將變成一個固定的數:6174。 例如:4321-1234=3087 8730-378=8352 8532-2358=6174 7641-1467=6147。 如果K位數也照此辦理,它們不是變成一個數,而是在幾個數字之間形成循環,例如對於五位數54321: 54321-12345=41976 97641-14679=82962 98622-22689=75933 97533-33579=63954 96543-34569=61974 97641-14679=82962 我們把82962 75933 63954 61974稱作循環節。在前面6174中,循環節認為只有一個數。 請輸出這些循環節之和,最終結果可能需要使用64位的整型才能存放。當沒有循環節,輸出0,例如:輸入33333,輸出0。 運行時間限制: 無限制 內存限制: 無限制 輸入: 輸入為一個正整數,取值范圍位0~0xffffffff 輸出: 輸出為各循環節的和 樣例輸入: 3214 樣例輸出: 6174
那其實用遞歸就可以解決了。
1.拆分每一位的數到vector
2.vector排序得到最大的數、最小的數
3.遞歸(出口條件,差值重復出現)
代碼。
#include <iostream> #include <vector> #include <algorithm> using namespace std; void cyclesum(int num,vector<int>& dis){ int size=0; vector<int> digits; while (num!=0){ digits.push_back(num%10); size++; num/=10; } sort(digits.begin(),digits.end()); int maxnum=0,minnum=0; for(int i=0;i<size;i++){ minnum=minnum*10+digits[i]; maxnum=maxnum*10+digits[size-i-1]; } int result=maxnum-minnum; if(result==0){ cout<<"0"<<endl; return; } if(find(dis.begin(),dis.end(),result)==dis.end()){ dis.push_back(result); return cyclesum(result,dis); } else{ auto j=find(dis.begin(),dis.end(),result); long ret=0; for(;j!=dis.end();j++) ret+=*j; cout<<ret<<endl; return; } } int main(){ int num=0; cin>>num; if(num==0) cout<<"0"<<endl; vector<int> dis; cyclesum(num,dis); return 0; }
