zoukankan      html  css  js  c++  java
  • P4999 烦人的数学作业

    考虑统计出每一个数位的出现次数,然后乘i求和

    DFS

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <queue>
    #define int long long 
    using namespace std ;
    const int ha = 1e9+7 ;
    int read() {
    	int x = 0 , f = 1 ; char s = getchar() ;
    	while(s > '9' || s < '0') {if(s == '-') f = -1 ; s = getchar() ;}
    	while(s <='9' && s >='0') {x = x * 10 + (s-'0'); s = getchar() ;}
    	return x*f ;
    }
    int f[20][20] , l , r , T , num[20] ;
    int dfs(int pos ,int sum ,int lead ,int limit ,int d) {
    	if(!pos) return sum ;
    	if(!lead&&!limit&&f[pos][sum] != -1) return f[pos][sum] ;
    	int up = limit ? num[pos] : 9 ;
    	int ans = 0 ;
    	for(int i = 0 ; i <= up ; i ++) {
    		ans += dfs(pos-1,sum+(i==d&&(!lead||i)),lead&&(i==0),limit&&(i==up),d) ;
    	}
    	if(!limit&&!lead) f[pos][sum] = ans%ha ;
    	return ans ;
    }
    int calc(int x,int d) {
    	int len = 0 ;
    	while(x) {
    		num[++len] = x % 10 ;
    		x /= 10 ; 
    	}
    	memset(f,-1,sizeof(f)) ;
    	return dfs(len,0,1,1,d) ;
    }
    signed main () {
    	T = read() ;
    	while(T --) {
    		l = read() , r = read() ;
    		int ans = 0 ;
    		for(int i = 0 ; i <= 9 ; i ++) {
    			ans += (calc(r,i) - calc(l-1,i))*i % ha ;
    		}
    		cout << (ans+ha)%ha << endl ;
    	}
    	return 0 ;
    }
    
    #include <bits/stdc++.h>
    #define int long long 
    using namespace std ;
    const int ha = 1e9+7 ;
    int T ; 
    int l , r  ;
    int f[20] , ten[20] , cnta[20] , cntb[20] ,num[20] ;
    void work(int x, int cnt[]) {
    	int len = 0 ;
    	while(x) {
    		num[++len] = x % 10 ;
    		x /= 10 ;
    	}
    	for(int i = len ; i >= 1 ; i --) {
    		for(int j = 0 ; j <= 9 ; j ++) {
    			cnt[j] =(cnt[j] +  f[i-1]*num[i]%ha)%ha ; //求出除了最高位以外的所有数的和
    		}
    		for(int j = 0 ; j < num[i] ; j ++) {
    			cnt[j] = (cnt[j] + ten[i-1] )%ha;//求出最高位单个数字的出现次数
    		}
    		int num2 = 0 ;
    		for(int j = i-1 ; j >= 1 ; j --) {
    			num2 = (num2 * 10 + num[j])%ha ;//加上最高位的数字出现个数
    		}
    		cnt[num[i]] = (cnt[num[i]]+num2 + 1)%ha ;
    		cnt[0] = (cnt[0]- ten[i-1]+ha)%ha ;
    	}
    } 
    signed main () {
    	scanf("%lld",&T) ;
    	ten[0] = 1 ;
    	for(int i = 1 ; i <= 19 ; i ++) {
    		f[i] = f[i-1] * 10 + ten[i-1] ; 
    		ten[i] = ten[i-1]*10 ;
    	}
    	while(T --) {
    		scanf("%lld%lld",&l,&r) ;
    		work(r,cnta) ;
    		work(l-1,cntb) ;
    		int ans = 0 ;
    		for(int i = 0 ; i <= 9 ; i ++) {
    			ans = (ans+(cnta[i]-cntb[i]+ha)*i%ha)%ha ;
    		}
    		memset(cnta,0,sizeof(cnta)) ;
    		memset(cntb,0,sizeof(cntb)) ;
    		printf("%lld
    ",(ans+ha)%ha) ;
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    [BZOJ1415]聪聪和可可
    [POJ2096]Collecting Bugs
    开博第一天
    实现CSS样式垂直水平完全居中
    Vue中独立组件之间数据交互
    python Template中substitute()的使用
    eclipse 编辑 python 中文乱码的解决方案
    java Math.random()随机数的产生
    java文件读写的两种方式
    My way on Linux
  • 原文地址:https://www.cnblogs.com/lyt020321/p/11756976.html
Copyright © 2011-2022 走看看