题解:P10262 [GESP样题 六级] 亲朋数
看到算法标签想出来的。
Idea
设 表示当前枚举到了第 位,子串化为十进制 对 取模的余数为 的子串数量。
设 对 取余的余数为 。
设 为上一个枚举到的 , 为我们需要转移的 ,由余数的性质我们可得:。其实就是将前一个数乘 然后加上 代表的十进制数对 取余的结果。
最后答案是什么?亲朋数是 的倍数,换而言之,亲朋数对 取模余数为 。所以答案就是 的和。
这题略卡空间,所以需要滚动数组优化。
Code
#include<bits/stdc++.h>
using namespace std;
long long dp[129],f[129];
int p;
string s;
long long ans=0;
int main(){
cin>>p;
cin>>s;
s=' '+s;
int n=s.length()-1;
for(int i=1;i<=n;i++){
int q=s[i]-'0';
q=q%p;
for(int j=0;j<p;j++){
f[j]=dp[j];
dp[j]=0;
}
for(int j=0;j<p;j++){
dp[(j*10+q)%p]+=f[j];
}
dp[q]++;//可能自己独自成为一个亲朋数,需要把这个数自己算上
ans+=dp[0];
}
cout<<ans;
return 0;
}
Tip
本题答案最多时可以达到 ,所以需要开 long long。例如当 , 由 个 构成时,所有情况都满足。
但是本题数据略水,所以不用开 long long 也能过。

浙公网安备 33010602011771号