鱼C论坛

 找回密码
 立即注册
查看: 2699|回复: 7

题目112:考察“跳跃数”的密度

[复制链接]
发表于 2016-8-21 00:59:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Bouncy numbers

Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, 134468.

Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, 66420.

We shall call a positive integer that is neither increasing nor decreasing a "bouncy" number; for example, 155349.

Clearly there cannot be any bouncy numbers below one-hundred, but just over half of the numbers below one-thousand (525) are bouncy. In fact, the least number for which the proportion of bouncy numbers first reaches 50% is 538.

Surprisingly, bouncy numbers become more and more common and by the time we reach 21780 the proportion of bouncy numbers is equal to 90%.

Find the least number for which the proportion of bouncy numbers is exactly 99%.


题目:

如果一个数的每一位都大于等于前一位,则称其为递增数,例如 134468。

类似的,如果一个数的每一位都小于等于前一位,则称其为递减数,例如 66420。

如果一个正整数既不是递增数也不是递减数,则称其为一个“跳跃数”,例如 155349。

显然 100 以下不存在任何跳跃数,但是 1000 以下的数中一半以上(525)个是跳跃数。事实上,跳跃数比例首次超过 50% 的数是 538。

令人惊奇的是,跳跃数的数量越来越多,到 21780 时跳跃数的比例已经达到 90%。

求使得跳跃数比例恰好等于 99% 的最小的数。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-8-31 17:28:26 | 显示全部楼层
1-1587002跳跃数有:1571132个比例:0.99
请按任意键继续. . .
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>
  4. #include <stdlib.h>
  5. using namespace std;
  6. //判断是否为跳跃数
  7. bool isz(int ma)
  8. {
  9.         string a;
  10.         char buf[20];
  11.         itoa(ma,buf,10);
  12.         string A(buf);
  13.         string B,C;
  14.         B=A;
  15.         C=A;
  16.         sort(B.begin(),B.end());
  17.         if(B==A)  return false;
  18.         reverse(C.begin(),C.end());
  19.         sort(C.begin(),C.end());
  20.         reverse(C.begin(),C.end());
  21.         if(C==A)  return false;
  22.        
  23.         return true;
  24. }
  25. int main()
  26. {
  27.         int m = 0;
  28.         double k;
  29.         for (int i = 1; i <10000000; i++)
  30.         {
  31.                 //跳跃数增加
  32.                 if(isz(i)) m++;
  33.                 //std::cout<<"1-"<<i<<"跳跃数有:"<<m<<"个";
  34.                 k=((double)m)/((double)i);
  35.         //        std::cout<<"比例:"<<k <<endl;
  36.                 if(k>=0.99f)
  37.                 {
  38.                         std::cout<<"1-"<<i<<"跳跃数有:"<<m<<"个";
  39.                         std::cout<<"比例:"<<k <<endl;
  40.                 system("pause");
  41.                 }
  42.         }
  43.         return 0;
  44. };
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-29 15:54:31 | 显示全部楼层
迷雾少年 发表于 2016-8-31 17:28
1-1587002跳跃数有:1571132个比例:0.99
请按任意键继续. . .

这题答案应该是1587000
  1. def isjump(n):
  2.         if n<100:
  3.                 return False
  4.         else:
  5.                 flagup, flagdown = 1, 1
  6.                 t1, m1 = n% 10, n//10
  7.                 while m1:
  8.                         if m1%10<=t1:
  9.                                 t1, m1 = m1%10, m1//10
  10.                         else:
  11.                                 flagup = 0
  12.                                 break
  13.                 t2, m2 = n% 10, n//10
  14.                 while m2:
  15.                         if m2%10>=t2:
  16.                                 t2, m2 = m2%10, m2//10
  17.                         else:
  18.                                 flagdown = 0
  19.                                 break
  20.                 if flagup == 0 and flagdown == 0:
  21.                         return True
  22.                 else:
  23.                         return False

  24. count = 0
  25. index = 0
  26. while True:
  27.         index += 1
  28.         if isjump(index):
  29.                 count += 1
  30.         if count/index == 0.99:
  31.                 print(index)
  32.                 break
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-15 17:09:35 | 显示全部楼层
思路就是先定义一个函数判别是否是跳跃数,然后从100开始穷举,直到跳跃数/总数=0.99为止。
  1. def is_jump(n):
  2.     if n < 100:
  3.         return False
  4.     up_flag, down_flag = 0, 0
  5.     l = len(str(n))
  6.     n0 = int(str(n)[0])
  7.     for i in range(1, l):
  8.         n1 = int(str(n)[i])
  9.         if n1 > n0:
  10.             up_flag = 1
  11.         if n1 < n0:
  12.             down_flag = 1
  13.         if up_flag == 1 and down_flag == 1:
  14.             return True
  15.         n0 = n1
  16.     return False

  17. jumps = 0
  18. n = 100
  19. while jumps / n != 0.99:
  20.     if is_jump(n):
  21.         jumps += 1
  22.     n += 1
  23. print(n)
复制代码

输出:
1587100
[Finished in 5.1s]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-26 19:55:34 | 显示全部楼层
jerryxjr1220 发表于 2017-5-15 17:09
思路就是先定义一个函数判别是否是跳跃数,然后从100开始穷举,直到跳跃数/总数=0.99为止。

输出:

兄,我的答案也是1587100,但是正确答案是1587000,奇怪了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-26 19:56:04 | 显示全部楼层
  1. import time
  2. st = time.time()
  3. def getBouncyNumtype(n):
  4.         if n < 10:
  5.                 return 3 #same
  6.         upflag,downflag = False, False
  7.         x, n = n%10, n//10
  8.         while n > 0:
  9.                 if n%10 < x: #increasing
  10.                         upflag = True
  11.                 elif n%10 > x: #decreasing
  12.                         downflag = True
  13.                 if upflag and downflag:
  14.                         return 0               
  15.                 x, n = n%10, n//10
  16.         if upflag:
  17.                 return 1
  18.         if downflag:
  19.                 return 2
  20.         return 3 #same

  21. n = 100
  22. cnt = 0
  23. while n//100 != n-cnt:               
  24.         t = getBouncyNumtype(n//100)
  25.         firstDigit = n//100 % 10
  26.         if t==1: #increasing
  27.                 cnt += 100 - (10-firstDigit+1)*(10-firstDigit)//2               
  28.         elif t==2: #decreasing
  29.                 cnt += 100 - (firstDigit+1+1)*(firstDigit+1)//2
  30.         elif t==0: #bouncy
  31.                 cnt += 100
  32.         else: # all same digit
  33.                 cnt += (10+firstDigit+2)*(9-firstDigit)//2 + (10+11-firstDigit)*firstDigit//2 - 9
  34.         n += 100
  35.         #if n==21800: break

  36. print(n, cnt, cnt/n) #1587100 1571229 0.99 #why 1587000
  37. print(time.time()-st) #0.031200170516967773
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-29 15:20:40 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2021-1-27 16:00 编辑
  1. def isBouncy(n):
  2.     n = [int(i)for i in str(n)]
  3.     r = range(1, len(n))

  4.     for i in r:    # increasing
  5.         if n[i-1] > n[i]:
  6.             break    # 如果不是递增数退出
  7.     else:
  8.         return False    # 如果没有退出返回False

  9.     for i in r:    # decreasing
  10.         if n[i-1] < n[i]:
  11.             break    # 如果不是递减数退出
  12.     else:
  13.         return False    # 如果没有退出返回False

  14.     return True


  15. bouncyCount = 0
  16. count = 100

  17. while bouncyCount * 100 - count * 99:
  18.     bouncyCount += isBouncy(count)
  19.     count += 1

  20. print(count)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-2 10:22:24 | 显示全部楼层
1587000

Process returned 0 (0x0)   execution time : 0.082 s
Press any key to continue.
这浮点精度怎么就这么迷……
  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;

  4. const int M = 2e6;
  5. const double EPS = 1e-15;

  6. bool is_incr(int x){
  7.   int curr,next = x % 10;
  8.   x /= 10;

  9.   while(x){
  10.     curr = x % 10;
  11.     if (next < curr)  return false;
  12.     next = curr;
  13.     x /= 10;
  14.   }
  15.   return true;
  16. }

  17. bool is_decr(int x){
  18.   int curr,next = x % 10;
  19.   x /= 10;

  20.   while(x){
  21.     curr = x % 10;
  22.     if (next > curr)  return false;
  23.     next = curr;
  24.     x /= 10;
  25.   }
  26.   return true;
  27. }


  28. int main(){
  29.   int cnt = 0;
  30.   for (int i = 1; ;i++){
  31.     if (is_incr(i) || is_decr(i) )  continue;
  32.     cnt++;

  33.     if (cnt / (double)(i) > 0.99) {cout << i << endl; break;}
  34.   }
  35.   //cout << cnt << endl;
  36.   return 0;
  37. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-21 15:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表