//公式递推 //列表找规律,比如读取各位为8,那么知道有1个被跳过,读取十位为3, 那么算从1到30共有多少位被跳过了,读取百位为5,计算从1到500共有多少位被跳过了 //然后分类讨论,读取的这个位数>=5时是1种情况,<5是另一种情况 #include<iostream> #include<cmath> using namespace std; int calculate(int n) { int ans = 0; int carry = 1; int bit = 1; if(n % 10 >= 5) ans++; n /= 10; while(n != 0) { int bit_num = n % 10; if(bit_num >= 5) { ans += (bit_num - 1) * carry + pow((double)10,double(bit)); } else if(bit_num < 5 && bit_num > 0) { ans += carry * bit_num; } carry = carry*9 + pow((double)10,double(bit)); n /= 10; bit++; } return ans; } int main() { int n; while(scanf("%d",&n)) { if(n == 0) break; printf("%d: %d/n",n,n - calculate(n)); } return 0; }