POJ3286 UVA11038 How many 0's?【位运算】

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3580 Accepted: 1944

Description

A Benedict monk No.16 writes down the decimal representations of all natural numbers between and including m and nm ≤ n. How many 0's will he write down?

Input

Input consists of a sequence of lines. Each line contains two unsigned 32-bit integers m and nm ≤ n. The last line of input has the value of m negative and this line should not be processed.

Output

For each line of input print one line of output with one integer number giving the number of 0's written down by the monk.

Sample Input

10 11
100 200
0 500
1234567890 2345678901
0 4294967295
-1 -1

Sample Output

1
22
92
987654304
3825876150

Source



问题链接POJ3286 UVA11038 How many 0's?

问题简述

  输入无符号整数m和n,满足m<=n,计算m到n(包括m和n)之间各个数中包含多少个0。

问题分析

  先分别计算0到m-1和0到n之间数的0个数,结果=0到n之间数的0个数-0到m-1之间数的0个数。计算0到n之间数的0个数时,先考虑1位数、2位数、......,在小于n的区间逐步统计。

程序说明

  数组radix[]计算存放10进制的位权备用。函数countzero()用于统计0到n之间数的0个数。

参考链接

  UVALive3261 UVA1640 POJ2282 HDU1663 ZOJ2392 The Counting Problem


AC的C语言程序如下:

/* POJ3286 How many 0's? */

#include <stdio.h>

typedef long long LL;

#define MAXN 10

LL radix[MAXN+1];

void maketable()
{
    int i;

    radix[0] = 1;
    for(i=1; i<=MAXN; i++)
        radix[i] = radix[i-1] * 10;
}

LL countzero(LL n)
{
    if(n < 0)
        return 0;

    LL sum = 1;
    int i = 1;
    while(radix[i] <= n) {
        LL digit, left, right;

        digit = n % radix[i] / radix[i - 1];
        if (digit == 0) {
            left = n / radix[i];
            right = n % radix[i - 1];
            sum += (left - 1) * radix[i - 1] + right + 1;
        } else {
            left = n / radix[i];
            sum += left * radix[i - 1];
        }

        i++;
    }

    return sum;
}

int main(void)
{
    maketable();

    LL m, n;

    while(scanf("%lld%lld", &m, &n) != EOF) {
        if(m == -1 && n == -1)
            break;

        printf("%lld\n", countzero(n) - countzero(m-1));
    }

    return 0;
}




### 关于 POJ 平台上的幂运算问题 在处理涉及幂运算的问题时,通常需要考虑以下几个方面: 1. **快速幂算法**:这是实现高效幂运算的核心方法。通过将指数分解为二进制形式并逐步平方计算基底的方式,可以显著降低时间复杂度至 \(O(\log n)\)[^1]。 2. **模运算优化**:许多问题要求对结果取模,因此可以在每一步计算过程中应用模运算,从而避免中间结果过大导致溢出或效率下降[^1]。 以下是基于上述原理的一个典型例子及其代码实现: #### 示例代码 假设我们需要验证某个数 \(p\) 是否满足 base-\(a\) 假伪素数条件(即对于非质数 \(p\) 和任意正整数 \(a\),\(a^{p} \equiv a \ (\text{mod}\ p)\) 成立),可以通过如下方式实现: ```cpp #include <iostream> using namespace std; // 快速幂函数 (带模运算) long long fast_pow(long long base, long long exp, long long mod) { long long result = 1; while (exp > 0) { if (exp % 2 == 1) { // 如果当前位是1,则累乘 result = (result * base) % mod; } base = (base * base) % mod; // 平方基数 exp /= 2; // 移动到下一位 } return result; } bool is_pseudoprime(long long a, long long p) { if (p == 1 || p == 0) return false; // 特殊情况排除 if (fast_pow(a, p, p) != a) return false; return true; } int main() { long long a, p; cin >> a >> p; if (is_pseudoprime(a, p)) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; } ``` 此代码片段展示了如何使用快速幂算法来判断一个数是否为假伪素数,并结合了模运算以提高效率和防止数据溢出。 另外,在更复杂的场景中可能还需要引入其他高级技术,比如 Miller-Rabin 质数测试用于大规模输入下的性能提升[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值