1的个数 南阳acm514

1的个数

时间限制: 1000 ms  |  内存限制:65535 KB
难度: 3
 
描述
给你两个数a和b,你的任务是计算出1在a和b之间出现的次数,比如说,如果a=1024,b=1032,那么a和b之间的数就是:
1024 1025 1026 1027 1028 1029 1030 1031 1032
则有10个1出现在这些数中。
 
输入
输入不会超过500行。每一行有两个数a和b,a和b的范围是0 <= a, b <= 100000000。输入两个0时程序结束,两个0不作为输入样例。
输出
对于每一对输入的a和b,输出一个数,代表1出现的个数。
样例输入
1 10
44 497
346 542
0 0
样例输出
2
185
40
来源
heroj
上传者
rihkddd
算法思想:首先,a不一定比b小,要判断一下,如果我们直接暴力从a到b每个值都判断肯定是会超时的,因为a和b的范围是0 <= a, b <= 100000000。什么??不信,那我们来看一下吧。
超时代码:
 1 #include
 2 int main()
 3 {
 4     int a,b,i,cut;
 5     while(scanf("%d%d",&a,&b)!=EOF,(a||b))
 6     {
 7         if(a > b)
 8         {
 9             int t = a;
10             a = b;
11             b = t;
12         }
13         cut = 0;
14         for(i=a; i<=b; i++)
15         {
16             int ans = i;
17             while(ans > 0)
18             {
19                 if(ans%10 == 1)
20                     cut++;
21                 ans/=10;
22             }
23         }
24         printf("%d\n",cut);
25     }
26     return 0;
27 }

  

我没骗你吧!下面我们来讲这题怎么做吧

算法思想:我们先求1~b 1的个数,在求1~(a-1)1的个数,然后再相减就等于a~b 1的个数了。求1~n 1的个数可以参考一下这个博客:https://blog.csdn.net/yi_afly/article/details/52012593  很详细!不说了,附上代码:

ac代码:

 

 1 #include
 2 #include
 3 using namespace std;
 4 int f(int n)
 5 {
 6     if(n < 1) return 0;
 7     int ans = 0;
 8     int base = 1;
 9     int round = n;
10     while(round > 0)
11     {
12         int weight = round%10;
13         round/=10;
14         ans+=round*base;
15         if(weight == 1)
16             ans+=(n%base)+1;
17         else if(weight > 1)
18             ans+=base;
19         base*=10;
20     }
21     return ans;
22 }
23 int main()
24 {
25     int a,b;
26     while(scanf("%d%d",&a,&b)!=EOF,(a||b))
27     {
28         if(a > b)
29         {
30             int t = a;
31             a = b;
32             b = t;
33         }
34         printf("%d\n",f(b)-f(a-1));
35     }
36     return 0;
37 }

 

 

你可能感兴趣的:(1的个数 南阳acm514)