牛客 吉林大學ACM集訓隊選拔賽 (重現賽)A 數位dp

被榜騙了 *** h題不是有手就會嗎 怎麼就那麼點人過啊 

不過我還是補a 數位dp 很久很久以前寫過 不要62 不過忘得乾乾淨淨了 

這題應該是數位dp裏面最簡單的那種吧 

鏈接:https://ac.nowcoder.com/acm/contest/5944/A
來源:牛客網
 

題目描述

One day, Ks raised a question in this contest.

How many times the digit 7\texttt{7}7 appears in the integer range of [0, n]?

The answer may be very large, please output the answer modulo 1 000 000 0071\,000\,000\,0071000000007.

 

輸入描述:


 

First line contains an integer T (1≤T≤100)T ~ (1 \leq T \leq 100)T (1≤T≤100), indicating the count of questions.

Each of the following T lines contains one integer n (1≤n≤10100000)n ~ (1 \leq n \leq {10}^{100000})n (1≤n≤10100000).

 

輸出描述:

Output T lines, one number per line representing the answer.
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char a[N];
typedef long long ll;
ll dp[N],_10pow[N],c[N];
const ll mod = 1e9+7;
ll ans;
void getans(int len){
	for(int i = len; i >= 1; i--)
		c[i]=a[len-i+1]-'0';
	for(int i = len; i >= 1; i--){
		ans+=dp[i-1]*c[i]%mod;//在第i位的情況下 7出現在後面的位
		ans%=mod;
		if(7<c[i]) ans+=_10pow[i-1];//7出現在第i位
		ans%=mod;
	}
	ll now = 0;
	for(int i = 1; i <= len; i++){//當某一位是7的時候 它出現的次數就是 它的後綴部分的大小+1
		if(c[i]==7) ans=(ans+now+1)%mod;
		now=(now+c[i]*_10pow[i-1])%mod;
	}
	printf("%lld\n",ans);
}
int main(){
	int t;
	scanf("%d",&t);
	_10pow[0]=1;
	for(int i = 1; i < N; i++){
		dp[i]=((dp[i-1]*10ll%mod)+_10pow[i-1])%mod;
		_10pow[i]=_10pow[i-1]*10ll%mod;
	}
	while(t--){
		scanf("%s",a+1);
		ans=0;
		int len=strlen(a+1); 
		getans(len);	
	}
	return 0;
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章