版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_40433389,未经博主允许不得转载。
1. 题意
这道题目的意思是寻找Forever number. “Forever number” is a positive integer A with K digits, satisfying the following constrains:
the sum of all the digits of A is m;
the sum of all the digits of A+1 is n; and
the greatest common divisor of m and n is a prime number which is greater than 2.
Now you are supposed to find these forever numbers.
给定K和m 寻找n和A
2. 题解
一开始拿到这道题,觉得又是和狼人杀一样绕的题目。又有gcd,又有素数,又有各个位数之和。
首先,我用暴力方法,尝试了从 10(k-1) 到10k 之间寻找符合条件的数字,结果后面两个测试点运行超时,也感觉很正常。接着我就做后面三道题,幸好后面三题比较简单。接着又来debug第一题。
我的想法一开始是寻找一个最小和最大的数,再在这个区间进行枚举。但是却一直找不到最小的那个数。后来仔细看了下题目,发现要先寻找质数n,心想着这是一个数学问题,我就分析了n需要满足哪个条件。
因为 A+1的各个位数和为n,A的各个位数和为m;m、n满足最小公约数为质数且大于2。因而A+1必须要有进位,也就是A的低位肯定含有不止一个9。假如含有一个9,A+1的各个位数之和就要减少8,意思m和n需要满足这样子的一个式子:m = n + 9 * t - 1 这边的t是指末位有几个9;
这样子进一步我们就能够列举 从3到m这边满足这样子关系式的n:(m-n+1) % 9 ==0 && isPrime(gcd(m,n))&&gcd(m,n) >2;找到这样子一个n之后,我们再去寻找A。A的寻找,我是从一个最小值开始的,这个最小值的求法也很简单,比如t=3 k =5,也就是末尾有3个9,于是我就从10999 开始寻找,接着每次加上 10t 次方,这样子枚举就不会超时了,而且最后的结果还能遵循 n从小到大,A也从小到大。
3. AC代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int isPrime(int n) {
if (n <= 1)
return 0;
for (int i = 2; i <= sqrt(n); i++) {
if (n%i == 0)
return 0;
}
return 1;
}
int gcd(int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a%b);
}
int digit(int n) {
string a = to_string(n);
int sum = 0;
for (int i = 0; i < a.length(); i++) {
sum = sum + a[i] - '0';
}
return sum;
}
int find_min(int nine, int k) {
string a;
for (int i = 0; i < k; i++) {
if (i == 0)
a = "1";
else
a += "0";
}
for (int i = k - 1; i >= k - nine; i--)
a[i] = '9';
return stoi(a);
}
int Hash[200];
int main() {
int n;
scanf("%d", &n);
int k, m;
int com;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &k, &m);
printf("Case %d\n", i);
int flag = 0;
if (m <= 9 * k) {
for (int j = 3; j < m; j++) {
int d = gcd(j, m);
if (isPrime(d) && d > 2) {
if ((m - j + 1) % 9 == 0) {
int nine = (m - j + 1) / 9;
int least = find_min(nine, k);
int maxn = pow(10, k);
for (int t = least; t < maxn; t+=pow(10,nine) ){
if (digit(t) == m && digit(t + 1) == j) {
flag = 1;
printf("%d %d\n", j, t);
}
}
}
}
}
}
if (flag == 0)
printf("No Solution\n");
}
system("pause");
return 0;
}