nowcoder數圈圈 | 51nod1042 數字0-9的數量

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述

tabris有一個習慣,無聊的時候就會數圈圈,無論數字還是字母。
現在tabris更無聊啦,晚上睡不着覺就開始數羊,從a只數到b只。
順便還數了a到b之間有多少個圈。

但是tabris笨啊,雖然數羊不會數錯,但很可能數錯圈的個數。
但是tabris很難接受自己笨這個事實,所以想問問你他一共應該數出多少個圈,這樣tabris纔好判斷他到底笨不笨啊。 

輸入描述:

輸入一個T,表示數據組數
每組測試數據包含兩個正整數a,b。
T∈[1,1000]
a,b∈[1,1014]

輸出描述:

每組數據輸出結果,並換行。
示例1

輸入

11
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
1 100

輸出

0
0
0
1
0
1
0
2
1
1
111

備註:

數字的圈的個數請根據樣例自行理解。

題意:0這個數字是一個圈,同樣的,4,6,9,都是一個圈,8是兩個圈,其他數字沒有圈,樣例給的很清楚。

思路:前兩天做過一道類似的題,跟這個做法一模一樣(https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042)。

先統計a到b這個區間(0-9)每個數字出現的個數,最後計算每個數字的貢獻。

現在問題是求每個數字出現了多少次。

舉個栗子:55211這個帶下劃線的位置出現了多少次的2(在1到55211這些數字中)

答案是55*100+11+1次   及(0-54)2(00-99),還有552(00-11);這個應該能看懂。

那如果統計這個位置3出現的次數呢? 答案是:55*100次 。    及(0-54)3(00-99)       553(..)沒有這樣的數字

那如果統計這個位置1出現的次數呢? 答案是:56*100次 。    及(0-55)1(00-99)

那麼這樣你就能統計這個位置可能出現的0-9這些數字各出現了多少次了,那麼你再枚舉每一個位置即可,複雜度就是9*(這個數字的位數)。

還有一種特殊情況:0的次數可能有偏差(因爲沒有前導0的存在)

舉個栗子:5000這個帶下劃線的位置出現了多少次的0(在1到1000這些數字中)

如果按照上面的規則計算的話,是5*100+1 次。   及(0-4)0(0-99)和50(00-00)顯然前面爲0的100次是不存在的(及00(00-99)),所以要減去這種情況。0出現的次數:個位減去1,十位減去10,百位減去100,以此類推。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
#define LL long long
#define N 50050
const LL mod=1e9+7;
using namespace std;
int v[20]= {1,0,0,0,1,0,1,0,2,1};
LL s[15];
void slove(LL x,int flag)
{
    LL sum=1,qian,zhong,hou;
    while(1)
    {
        qian=x/sum/10;
        zhong=x/sum%10;
        hou=x%sum;
        if(hou==x) break;
        for(int i=0; i<10; i++)
        {
            if(i<zhong) s[i]+=(qian+1)*sum*flag;
            else if(i==zhong) s[i]+=(qian*sum+hou+1)*flag;
            else if(i>zhong) s[i]+=(qian*sum)*flag;
        }
        s[0]-=sum*flag;
        sum*=10;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(s,0,sizeof s);
        LL a,b;
        scanf("%lld%lld",&a,&b);
        slove(b,1);
        slove(a-1,-1);
        LL ans=0;
        for(int i=0; i<10; i++)
            ans+=v[i]*s[i];
        printf("%lld\n",ans);
    }
}














發佈了156 篇原創文章 · 獲贊 56 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章