【2019秋pat乙级真题】2019秋pat考试7-4天长地久数 思路分析(20分)

2019秋pat考试7-4天长地久数

题目:
“天长地久数”是指一个 K 位正整数 A,其满足条件为:A 的各位数字之和为 m,A+1 的各位数字之和为 n,且 m 与 n 的最大公约数是一个大于 2 的素数。本题就请你找出这些天长地久数。

输入格式:
输入在第一行给出正整数 N(≤5),随后 N 行,每行给出一对 K(3<K<10)和 m(1<m<90),其含义如题面所述。

输出格式:
对每一对输入的 K 和 m,首先在一行中输出 Case X,其中 X 是输出的编号(从 1 开始);然后一行输出对应的 n 和 A,数字间以空格分隔。如果解不唯一,则每组解占一行,按 n 的递增序输出;若仍不唯一,则按 A 的递增序输出。若解不存在,则在一行中输出 No Solution。

输入样例:

2
6 45
7 80

输出样例:

Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution

代码
20分通过

#include<iostream>
#include<string>
#include<math.h>
using namespace std;
typedef struct num {
	int k;
	int m;
	bool is=true;
}Num;
int max(int m, int n) {
	return n == 0 ? m : max(n, m%n);
}
bool isprime(int ax) {
	bool is = true;
	if (ax > 2) {
		for (int i = 2; i <=sqrt((double)ax); i++) {
			if (ax%i == 0) {
				is = false;
				break;
			}
		}
	}
	else is = false;
	return is;
}
void Print(int k,int count,int r) {
	string A = ""; string B = ""; string C = "";
	int i = 0;
	while (i < count) {
		B += "9";
		i++;
	}
	for (int j = pow(10, k - count - 1); j < pow(10, k - count); j++) {
		A = to_string(j);
		int sum = 0;
		for (int i = 0; i < k - count; i++) {
			sum = A[i] - '0' + sum;
		}
		int sum1 = 0;
		C =to_string(j + 1);
		for (int i = 0; i < C.length(); i++) {
			sum1 = C[i] - '0' + sum1;
		}
		if (sum == r - 1&&sum1==r)//不光要判断前几位和是否相同,还要判断加1之后的和是否相同
		 {
			cout << r << " " << A+B << endl;
		}
	}
}
int main() {
	Num n[6];
	int N;
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> n[i].k >> n[i].m;
		if (n[i].k * 9 <= n[i].m)n[i].is = false;
	}
	for (int i = 0; i < N; i++) {
		cout << "Case " << i + 1 << endl;
		if (n[i].is == false) {
			
			cout << "No Solution" << endl;
		}
		else 
		{
			int q = 0;
			int count = n[i].m / 9;
			int r = n[i].m % 9;
			bool flag;
			if (r == 0) {
				count--;
				r = r + 9 + 1;
				flag = isprime(max(n[i].m, r));
				if (flag) {
					n[i].is = true;
					Print(n[i].k, count, r);
				}
				else {
					cout << "No Solution" << endl;
				}
				
			}
			else {
				r = r + 1;
				flag = isprime(max(n[i].m, r));
				if (flag) {
					n[i].is = true;
					Print(n[i].k, count, r);
				}
				else {
					q = r - 1;
				}
				if (q != 0) {
					bool p = false;
					q = q + 1;
					while (count > 1) {
						count--;
						q = q + 9;
						flag = isprime(max(n[i].m, q));
						if (flag) {
							n[i].is = true;
							Print(n[i].k, count, q);
							p = true;
						}
					}
				 if (p == false) {
					cout << "No Solution" << endl;
					}
				}
			}
		}
	}
	return 0;
}

思路:

  1. 判断输入的k与m的关系,k位数字各个位数之和最大为9k(9乘k),如果m大于等于9k,显然,这种情况没有数字,则标记为false。没有被标记的就是true了。

  2. 遍历输入的数据,如果为false,直接输出“No Solution”,如果为true,跳到步骤3

  3. 令count=m/9,count为9的位数,r=m%9,则r为剩余位数的和。

  4. 如果r为0,则说明数字A的后count-1位为9,前k-count+1位的和为9。将A+1后得到的数字各个位数相加得n,n为10。n也只能为10。判断n与m的最大公约数是否是素数,如果是素数,则满足题目要求,输出满足数字A的所有情况。如果不是素数,则输出“No Solution”。

  5. 如果r不为0,则有两种情况,情况一:数字A有count个9,前k-count位和为r,则A+1后得到的n为r+1,判断n与m的最大公约数是否是素数,如果是素数,则满足题目要求,输出满足数字A的所有情况。如果不是素数,跳到情况二。

  6. 情况二:如果count>1,往下执行,否则跳到步骤7。数字A有count-1个9,前k-count+1为的和为r=r+9,A+1后得到的n就为r+1了。判断n与m的最大公约数是否是素数,如果是素数,则满足题目要求,输出满足数字A的所有情况,p为false,如果输出了,则标记p=true。如果不是素数,则让count=count-1,返回步骤6。

  7. 如果p为false则输出“No Solution”。

注意:

  1. 数字A满足了和为n-1,A+1也要满足和为n。(注意前提)
  2. 什么情况下输出“No Solution”,第一次提交得10分,扣了10分就是因为输出问题。

写的比较详细。。。有些可能词不达意,用纸笔写出来可能会比较好理解。可能其他大佬有更简单的方法,欢迎交流!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值