PE 111 Primes with runs (数位dp)

旧城等待, 2022-07-13 11:42 196阅读 0赞

Primes with runs

Problem 111

Considering 4-digit primes containing repeated digits it is clear that they cannot all be the same: 1111 is divisible by 11, 2222 is divisible by 22, and so on. But there are nine 4-digit primes containing three ones:

1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111

We shall say that M(n, d) represents the maximum number of repeated digits for an n-digit prime where d is the repeated digit, N(n, d) represents the number of such primes, and S(n, d) represents the sum of these primes.

So M(4, 1) = 3 is the maximum number of repeated digits for a 4-digit prime where one is the repeated digit, there are N(4, 1) = 9 such primes, and the sum of these primes is S(4, 1) = 22275. It turns out that for d = 0, it is only possible to have M(4, 0) = 2 repeated digits, but there are N(4, 0) = 13 such cases.

In the same way we obtain the following results for 4-digit primes.






































































Digit, d M(4, d) N(4, d) S(4, d)
0 2 13 67061
1 3 9 22275
2 3 1 2221
3 3 12 46214
4 3 2 8888
5 3 1 5557
6 3 1 6661
7 3 9 57863
8 3 1 8887
9 3 7 48073

For d = 0 to 9, the sum of all S(4, d) is 273700.

Find the sum of all S(10, d).

题意:

有重复数字的素数

考虑一个有重复数字的4位素数,显然这4个数字不能全都一样:1111被11整除,2222被22整除,依此类推;但是,有9个4位素数包含有三个一:

1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111

我们记M(n, d)是n位素数中数字d重复出现的最多次数,N(n, d)是这类素数的个数,而S(n, d)是这类素数的和。

因此M(4, 1) = 3是4位素数中数字1重复出现的最多次数,有N(4, 1) = 9个这类素数,而它们的和是S(4, 1) = 22275。还能得出,对于d = 0,在4位素数中最多重复出现M(4, 0) = 2次,但是有N(4, 0) = 13个这类素数。

同样地,我们可以得到4位素数的如下结果。








































































数字d M(4, d) N(4, d) S(4, d)
0 2 13 67061
1 3 9 22275
2 3 1 2221
3 3 12 46214
4 3 2 8888
5 3 1 5557
6 3 1 6661
7 3 9 57863
8 3 1 8887
9 3 7 48073

对于d = 0至9,所有S(4, d)的和为273700。

求所有S(10, d)的和。

题解:暴力也行,大概1min,数位dp更快,100ms。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. set<ll>s;
  5. int isPrime(ll n)
  6. {
  7. for(ll i=2;i<=(ll)sqrt(n);i++){
  8. if(n%i==0)return 0;
  9. }
  10. return 1;
  11. }
  12. void gao(ll num, int pos, int len, int repeat_Dig, int num_repeat_Dig, set<ll>& s)
  13. {
  14. if(len - pos < num_repeat_Dig) return;
  15. if(pos == len)
  16. {
  17. if(isPrime(num))
  18. {
  19. s.insert(num);
  20. }
  21. return ;
  22. }
  23. if(num_repeat_Dig != 0 && !(repeat_Dig == 0 && pos == 0))
  24. {
  25. gao(num * 10 + repeat_Dig, pos + 1, len, repeat_Dig, num_repeat_Dig - 1, s);
  26. }
  27. for(int i = pos == 0 ? 1 : 0; i <= 9; i++)
  28. {
  29. if(i == repeat_Dig) continue;
  30. gao(num * 10 + i, pos + 1, len, repeat_Dig, num_repeat_Dig, s);
  31. }
  32. return ;
  33. }
  34. int main()
  35. {
  36. int n;
  37. cin>>n; //位数
  38. ll ans = 0;
  39. for(int dig = 0; dig <= 9; dig++) //数字dig重复次数最多的数
  40. {
  41. s.clear();
  42. for(int num_repeat_Dig = n; num_repeat_Dig >= 1; num_repeat_Dig--)
  43. {
  44. gao(0, 0, n, dig, num_repeat_Dig, s);
  45. if(!s.empty())
  46. {
  47. ll sum = 0;
  48. for(set<ll>::iterator it=s.begin();it !=s.end();++it)
  49. {
  50. sum += *it;
  51. //cout<<*it<<endl;
  52. }
  53. cout<<sum<<endl;
  54. ans += sum;
  55. break;
  56. }
  57. }
  58. }
  59. cout<<"ans="<<ans<<endl;
  60. return 0;
  61. }

发表评论

表情:
评论列表 (有 0 条评论,196人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数位DP 详解

    序 > 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分。 以下是数位DP详解,涉及到的例题有:

    相关 数位dp小结

    数位dp小结 关于limit的问题 在数位dp中,limit的作用主要有两个。 控制枚举的界限,倘若没有界限,每一位的枚举范围都是0-9. 但如果有界限,

    相关 数位DP

    Problem Description 据说,QAQ 的幸运数字是含有 "47" (4 和 7 相邻)的数,例如 47, 147, 247, 470, 471, 2047

    相关 数位DP UVA - 11038

    数位DP,顾名思义,是在个位,十位,百位,千位…….这些数的数位上进行的DP,它其实就是一种暴力枚举+记忆化搜索。 数位DP一般用来解决要求找出某个区间内,满足要求的数有多