7-1 Forever (20 分)
"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.
Input Specification
Each input file contains one test case. For each test case, the first line contains a positive integer N(≤5) N(≤5) . Then N lines follow, each gives a pair of K(3<K<10) K(3<K<10) and m(1<m<90) m(1<m<90) , of which the meanings are given in the problem description.
Output Specification
For each pair of K and m, first print in a line Case X
, where X
is the case index (starts from 1). Then print n and A in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of n. If still not unique, output in the ascending order of A. If there is no solution, output No Solution
.
Sample Input
2
6 45
7 80
Sample Output
Case 1 10 189999 10 279999 10 369999 10 459999 10 549999 10 639999 10 729999 10 819999 10 909999 Case 2 No Solution
【声明】
由于此题还未上PAT官网题库,故没有测试集,仅仅是通过了样例,若发现错误,感谢留言指正。
Solution:
这道题可以使用暴力,但一定要在过程中进行判断,从而减少循环次数。
一般暴力的对手就是DFS了,所以这道题使用DFS比较简单
不过重点就是要及时剪枝,不然和暴力没区别了
具体的在代码的注释中有说明。
【突然发现个规律,满足条件的永远是后k-2位都是9,0-1位是和为m- 9*(k-2) 的组合,若这个规律成立,那就简单多了^…^】
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <algorithm> 5 using namespace std; 6 int nums, k, m, n; 7 vector<pair<int, int>>res; 8 int divisor(int a, int b)//求最大公约数 9 { 10 if (a%b == 0) 11 return b; 12 return divisor(b, a % b); 13 } 14 bool isPrime(int x)//判断是不是大于的素数 15 { 16 if (x <= 2)return false; 17 for (int i = 2; i*i <= x; ++i) 18 if (x%i == 0)return false; 19 return true; 20 } 21 int getSum(int x) 22 { 23 int sum = 0; 24 while (x) 25 { 26 sum += x % 10; 27 x /= 10; 28 } 29 return sum; 30 } 31 bool check(int a) 32 { 33 int b = a + 1; 34 n = 0; 35 while (b) 36 { 37 n += b % 10; 38 b /= 10; 39 } 40 if (isPrime(divisor(m, n))) 41 return true; 42 else 43 return false; 44 } 45 void DFS(string &str, int index, int digit, int sum) 46 { 47 if (index >= k || sum > m)return;//不能超过k位,从0开始 48 if (sum + 9 * (k - index - 1) < m)return;//第index数字太小,以至于其他位数全部填9其和都达不到m 49 str[index] = digit + '0';//这步要写在前哦,因为sum已经加上了 50 if (sum == m && index == k - 1)//满足要求 51 { 52 int a = stoi(str.c_str()); 53 if (check(a)) 54 res.push_back(make_pair(n, a)); 55 return; 56 } 57 for (int i = 0; i < 10; ++i) 58 DFS(str, index + 1, i, sum + i); 59 } 60 int main() 61 { 62 cin >> nums; 63 for (int i = 1; i <= nums; ++i) 64 { 65 cin >> k >> m; 66 res.clear(); 67 string str(k, '0'); 68 for (int j = 1; j < 10; ++j) 69 DFS(str, 0, j, j);//第一位不能为0 70 sort(res.begin(), res.end(), [](pair<int, int>v1, pair<int, int>v2) {//排序 71 if (v1.first == v2.first) 72 return v1.second < v2.second; 73 return v1.first < v2.first; 74 }); 75 printf("Case %d\n", i); 76 if (res.size() > 0) 77 for (auto a : res) 78 cout << a.first << " " << a.second << endl; 79 else 80 printf("No Solution\n"); 81 } 82 return 0; 83 }