文章目录

  • 题目
  • 解题思路
    • 1.辗转相除法求最大公约数
      • **同理计算最小公倍数:**
    • 2.分情况讨论在哪些数之间暴搜
  • AC代码

题目

“天长地久数”是指一个 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

解题思路

1.辗转相除法求最大公约数

必须掌握如何求最大公约数(greatest common divisor):辗转相除法

int gcd(int m, int n){if (m < n){int t = m;m = n;n = t;}return n == 0 ? m : gcd(n, m%n);
}

辗转相除法是求最大公约数的一种方法。它的具体做法是:用较小数除较大数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。
如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。这个和更相减损术有着异曲同工之处。

原理:

首先介绍下更相减损术的原理,假设有两个数161和63,我们要求这两个数的最大公因数,不妨假定这个最大公因数为m,我们可以将较大的数161看成63+98,63与98的和161可以被m整除,其中63也可以被m整除,自然98可以被m整除;
所以这个问题就转换为求98和63的最大公因数m(和上面m相等)
将98看成63+35,其中63可以被m整除,和98也能被m整除,故35也可以被m整除;
所以问题进一步转换为求35和63的最大公因数m(和上面m相等)
同理转换为求 (63-35)=>28和35 的最大公因数
然后转换为求28和7的最大公因数
…(一直减呀减)
后来转换为求7和7的最大公因数
最后转换为求7和0的最大公因数
输出第一个数字即可;这就是相减损术的原理
我们发现求28和7的最大公约数,一直减7,一直减7…减到不能减为止。这个不断减7的过程就是除7求余数(即%7)
这样我们可以将相减损术优化成辗转相除法

同理计算最小公倍数:

只要用这两个数的乘积除以最大公因数即可
printf(“lcm=%d\n”,a*b/gcd(a,b))
————————————————
原文链接:https://blog.csdn.net/weixin_43886797/article/details/85569998

2.分情况讨论在哪些数之间暴搜

2.忽略如何取数的过程,分情况讨论(A)和(A+1)的各数和m,n的最大公约数应为多少

涉及到了进位与否,分为以下几种:

  1. 当A的末尾数不为9时,A+1不进位

    n=m+1 互质,不满足条件

  2. 当A的末尾数为9时,A+1进一位

    例:129和130(12和4);159和160(15和7)
    n=m+8,则最大公约数必然是8的因子(1,2,4,8),唯一的质数2不满足条件

  3. 当A的末尾数为99时,A+1进两位
    例:199和200(19和2);1099和1100(19和2)
    n=m+17,则 最大公约数必然是17的因子(1,17),17就满足条件

从末尾数为99开始就出现了满足条件的数,则最起码末尾两位为99不变进行暴搜寻找符合条件的数,大大减少了暴搜的次数

使用暴搜的原因是因为和dfs一样都得搜索这么多遍

bool cmp(yys a, yys b){if (a.n != b.n)return a.n < b.n;elsereturn a.num < b.num;
}
void tcdj(int k, int m){long long int minm=1, i,t;//minm即为k-2位的最小数(最后两位是99),i是暴搜的数int n,sum=0;yys yy[10001];//有缘数的集合for (int j = 1; j < (k-2); j++)minm *= 10;//直接从10````99这个最小数开始循环,每次加100,这样尾数就不会变for (i = minm * 100 + 99; i < minm * 1000; i += 100){if (compute(i) == m){n = compute(i + 1);if (issu(gcd(m, n))){yy[sum].num = i;yy[sum++].n = n;}}}if (sum==0)printf("No Solution\n");else{sort(yy,yy+sum, cmp);for (int j = 0; j < sum; j++)printf("%d %lld\n", yy[j].n, yy[j].num);}
}

AC代码

#include<stdio.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int N, num[10][2];
typedef struct yys{long long int num;int n;
}yys;
int gcd(int m, int n){if (m < n){int t = m;m = n;n = t;}return n == 0 ? m : gcd(n, m%n);
}
bool issu(int x){if (x < 3)return false;elsefor (int i = 2; i <= sqrt(x); i++)if (x%i == 0)return false;return true;}
int compute(long long int t){int len = 0;while (t != 0){len += t % 10;t /= 10;}return len;
}
bool cmp(yys a, yys b){if (a.n != b.n)return a.n < b.n;elsereturn a.num < b.num;
}
void tcdj(int k, int m){long long int minm=1, i,t;//minm即为k-2位的最小数(最后两位是99),i是暴搜的数int n,sum=0;yys yy[10001];//有缘数的集合for (int j = 1; j < (k-2); j++)minm *= 10;//直接从10````99这个最小数开始循环,每次加100,这样尾数就不会变for (i = minm * 100 + 99; i < minm * 1000; i += 100){if (compute(i) == m){n = compute(i + 1);if (issu(gcd(m, n))){yy[sum].num = i;yy[sum++].n = n;}}}if (sum==0)printf("No Solution\n");else{sort(yy,yy+sum, cmp);for (int j = 0; j < sum; j++)printf("%d %lld\n", yy[j].n, yy[j].num);}
}
int main(){scanf("%d", &N);for (int i = 1; i <= N; i++){scanf("%d%d", &num[i][0], &num[i][1]);}for (int i = 1; i <= N; i++){printf("Case %d\n", i);tcdj(num[i][0], num[i][1]);}system("PAUSE");return 0;
}

7-4 天长地久 (20分)相关推荐

  1. 天长地久 (20分)

    天长地久 (20分) PAT2019秋季真题 "天长地久数"是指一个 K 位正整数 A,其满足条件为:A 的各位数字之和为 m,A+1 的各位数字之和为 n,且 m 与 n 的最大 ...

  2. PAT 1104 天长地久 (20 分) C语言

    这个题目的关键在于对代码的简化,很容易就超时,所以一定要尽可能简化,我的简化思路放在文章最后,欢迎参考与指正. 题目: 1104 天长地久 (20 分) "天长地久数"是指一个 K ...

  3. 1104. 天长地久 (20 分)

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

  4. 1104 天长地久 (20 分)

    分析 通过率感人的题目 考点 搜索 剪枝 排序 质数 最大公约数 思路 首先看到数值的位数最高达9位,所以暴力枚举肯定是会超时的,然后看到数据范围比较小,可以直接枚举加剪枝. 我一直卡在第三个测试点, ...

  5. 7-1 查找书籍(20 分)(程序设计天梯赛模拟练习题)

    7-1 查找书籍(20 分) 给定n本书的名称和定价,本题要求编写程序,查找并输出其中定价最高和最低的书的名称和定价. 输入格式: 输入第一行给出正整数n(<10),随后给出n本书的信息.每本书 ...

  6. PTA—输出全排列 (20分) 递归回溯思想

    PTA-输出全排列 (20分) 递归回溯思想 题目要求: 请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间. 输入格式: 输入给出 ...

  7. 2、求100以内的素数之和。(20分)

    题目: /* 2.求100以内的素数之和.(20分) */ 代码: public class Two207 {public static void main(String[] args) {int s ...

  8. 1、输入四个整数,按照从小到大顺序输出。(20分)

    题目: /* 1.输入四个整数,按照从小到大顺序输出.(20分) */ 代码: 注:题目说的是四个数的排序,我就直接写了个冒泡排序 public class One207 {public static ...

  9. /* * 编程题第五题(20分): 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“

    题目: 编程题第五题(20分): 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印 *****************    所谓" ...

最新文章

  1. 关于组织参加2020年全国大学生智能汽车竞赛山东赛区比赛的通知
  2. Codeforces Round #312 (Div. 2)
  3. zookeeper源码分析之三客户端发送请求流程
  4. 关于文本编辑器我为什么墙裂推荐你使用Notepad++
  5. SCCM2007 R2统计软件使用频率,SCCM系列之七
  6. 秒懂云通信:如何用阿里云语音通知服务(小白指南)
  7. 【英语学习】【English L06】U03 House L1 What type of apartment do you want to rent?
  8. 【英语学习】【医学】Unit 03 Blood
  9. 列表解析python_Python 列表解析
  10. 在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录...
  11. python多环境管理_Python多版本环境管理之pyenv
  12. golang 关闭gc 并手动gc_Golang垃圾回收 屏障技术
  13. Leetcode每日一题:10.09.sorted-matrix-search-lcci(排序矩阵查找)
  14. 软件测试管理是什么?
  15. 关于引用mshtml的问题
  16. matlab中的freqz函数是什么意思,的频率响应函数freqz().ppt
  17. 体育硕士代码_研究生专业代码是什么
  18. python测试开发django-114.ModelForm中局部钩子(clean_)和全局钩子校验
  19. Ember Model
  20. 广东开放大学形考任务保险学原理(本,2022春)形考三答案

热门文章

  1. GPT-4王者加冕!读图做题性能炸天,凭自己就能考上斯坦福
  2. web开发需要用什么软件
  3. C# WinForm 使用SMTP协议发送QQ邮箱验证码
  4. 【Kotlin】告别KAPT,拥抱KSP API
  5. 保存相片是什么图像格式?
  6. 华为软件测试实习生面试
  7. 三维视频融合 开放源代码 混合模式 内嵌web容器 c++ js 混合开发 时空克隆引擎 数字孪生 点卯 系列 魔镜系列
  8. 安卓病毒频发,做好手机安全防护很有必要
  9. solidworks钣金学习分享
  10. MACD与KDJ合二为一指标公式怎么编写?