PAT (Advanced Level) 1160 Forever——gcd+prime

PAT (Advanced Level) 1160 Forever——gcd+prime,第1张

题目传送门

终于遇到了数论题
题目不难但是略微复杂

A(K位)是Forever number当且仅当

  • A每一位的数值之和为m
  • A+1每一位的数值之和为n
  • m和n的最大公约数是大于2的素数

dfs枚举A的每一位,通过m(A每一位的数值之和)剪枝
需要注意,在输出时需要按照n排序,若n相等则按照A排序

#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;

int k, m;
int a[15];
int flag = 0;
struct node {
	int n;
	LL A;
};
node ans[1000];
int cnt;

int cmp(node &X,node &Y) {
	if (X.n != Y.n) return X.n < Y.n;
	else return X.A < Y.A;
}

int gcd(int n, int m) {
	int r = n % m;
	while (r) {
		n = m;
		m = r;
		r = n % m;
	}
	return m;
}

void check() {
	LL num1 = 0;
	for (int i = 1; i <= k; ++i)
		num1 = num1 * 10 + (LL)a[i];
	LL num2 = num1 + 1;
	int n = 0;
	while (num2) {
		n += int(num2 % 10);
		num2 /= 10;
	}
	int c = gcd(n, m);
	if (c <= 2) return;
	for (int i = 2; i <= (int)ceil(sqrt(c)); ++i)
		if (c % i == 0) return;
	cnt++;
	ans[cnt].n = n;
	ans[cnt].A = num1;
}

void dfs(int t, int res) {
	if (t > k) {
		if (res == 0) check();
		return;
	}
	int s = 0;
	if (t == 1) s = 1;
	for (int i = s; i <= min(9,res); ++i) {
		a[t] = i;
		dfs(t + 1, res - i);
		a[t] = 0;
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	for (int i = 1; i <= T; ++i) {
		scanf("%d%d", &k, &m);
		cnt = 0;
		printf("Case %d\n",i);
		dfs(1, m);
		if (!cnt) printf("No Solution\n");
		else {
			sort(ans + 1, ans + 1 + cnt, cmp);
			for (int j = 1; j <= cnt; ++j)
				printf("%d %lld\n", ans[j].n, ans[j].A);
		}
	}
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1295908.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-10
下一篇2022-06-10

发表评论

登录后才能评论

评论列表(0条)

    保存