hdu5902,5505——GCD小合集
来源:互联网 发布:网络优化与维护 编辑:程序博客网 时间:2024/06/05 05:47
一次校内比赛中碰到这两个题,有一次加深了对GCD的认识
hdu5902
题目链接
http://acm.split.hdu.edu.cn/showproblem.php?pid=5902
GCD is Funny
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 860 Accepted Submission(s): 227
Problem Description
Alex has invented a new game for fun. There are n integers at a board and he performs the following moves repeatedly:
1. He chooses three numbersa ,b and c written at the board and erases them.
2. He chooses two numbers from the triplea ,b and c and calculates their greatest common divisor, getting the number d (d maybe gcd(a,b) ,gcd(a,c) or gcd(b,c) ).
3. He writes the numberd to the board two times.
It can be seen that after performing the moven−2 times, there will be only two numbers with the same value left on the board. Alex wants to know which numbers can left on the board possibly. Can you help him?
1. He chooses three numbers
2. He chooses two numbers from the triple
3. He writes the number
It can be seen that after performing the move
Input
There are multiple test cases. The first line of input contains an integerT (1≤T≤100) , indicating the number of test cases. For each test case:
The first line contains an integern (3≤n≤500) -- the number of integers written on the board. The next line contains n integers: a1,a2,...,an (1≤ai≤1000) -- the numbers on the board.
The first line contains an integer
Output
For each test case, output the numbers which can left on the board in increasing order.
Sample Input
341 2 3 442 2 2 255 6 2 3 4
Sample Output
1 221 2 3
Source
BestCoder Round #87
Recommend
wange2014 | We have carefully selected several similar problems for you: 6022 6021 6020 6019 6018
题意比较好懂,一个数组每个数任意两两求最大公约数后,把得到的GCD放入数组进行更新。
然后对更新后的数组再次求GCD(一共n-2次操作),输出最后的GCD
题意不难,就是用标记数组多次求GCD的思想比较重要
代码:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<vector>#include<set>#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;int gcd(int x,int y){ return y?gcd(y,x%y):x;}int main(){ int T,n,t; int i,j,k; int a[1005],vis[1005]/*标记数组*/; scanf("%d",&T); while(T--){ scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d",&a[i]); } memset(vis,0,sizeof(vis)); for(i=0;i<n-1;i++){ ///对原数组中的数两两GCD for(j=i+1;j<n;j++){ vis[gcd(a[i],a[j])]=1; } } int t=1; ///标记是否有新的GCD产生 int len=1; while(t&&len<n-2){ ///一共n-2次操作 t=0; len++; for(i=1;i<=1000;i++){ ///对于更新后的数组再次GCD for(j=0;j<n;j++){ if(vis[i]&&!vis[gcd(i,a[j])]){ t=1; vis[gcd(i,a[j])]=1; } } } } t=1; for(i=0;i<=1000;i++){ if(vis[i]){ if(t){ printf("%d",i); t=0; } else printf(" %d",i); } } printf("\n"); } return 0;}
题目链接
http://acm.split.hdu.edu.cn/showproblem.php?pid=5505
GT and numbers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2115 Accepted Submission(s): 546
Problem Description
You are given two numbers N and M .
Every step you can get a newN in the way that multiply N by a factor of N .
Work out how many steps canN be equal to M at least.
If N can't be to M forever,print−1 .
Every step you can get a new
Work out how many steps can
If N can't be to M forever,print
Input
In the first line there is a number T .T is the test number.
In the nextT lines there are two numbers N and M .
T≤1000 ,1≤N≤1000000 ,1≤M≤263 .
Be careful to the range of M.
You'd better print the enter in the last line when you hack others.
You'd better not print space in the last of each line when you hack others.
In the next
Be careful to the range of M.
You'd better print the enter in the last line when you hack others.
You'd better not print space in the last of each line when you hack others.
Output
For each test case,output an answer.
Sample Input
31 11 22 4
Sample Output
0-11
Source
BestCoder Round #60
Recommend
hujie | We have carefully selected several similar problems for you: 6022 6021 6020 6019 6018
题意:给定n,m两个数,求n乘几次n的因子可以得到m,输出乘法次数,永远得不到输出-1
可以用GCD逐步逼近目标解
代码:
#pragma GCC optimize("03")///适当的加速#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;typedef unsigned long long ll;///long long爆了,WAll gcd(ll x,ll y){ return y?gcd(y,x%y):x;}int main(){ int T,t; ll n,m,ans; int i,j,k; scanf("%d",&T); while(T--){ t=0; scanf("%llu %llu",&n,&m); if(n>m||m%n||(n==1&&m!=1)){ ///排除特例 printf("-1\n"); continue; } else{ while(n!=m){ ans=gcd(n,m/n); //每次要乘的最大因子 if(ans==1){//遇到有1的情况,变为特例 t=-1; break; } n*=ans; ///对n进行更新,逐渐接近m t++; } printf("%d\n",t); } } return 0;}用一组举例分析
Input
6 7776
Output
3
n=6 m=7776 ans=6
n=6*6 t++
n=36 m=7776 ans=36
n=36*36 t++
n=1296 m=7779 ans=6
n=1296*6 t++
n=m
对于这道题还有一个坑点就是数据范围
摘一段其他博文的内容:
/****************************************************/
转自:http://blog.csdn.net/queuelovestack/article/details/49210173
出题人的解题思路:
1002 GT and numbers
如果A大于B那么显然无解。
考虑把A和B分解质因数。
若B存在A没有的质因数也显然无解。
对于某一个A的质因数的次数。为了加速接近B,它一定是每次翻倍,最后一次的时候把剩下的加上。
那么答案就是最小的k使得2k∗Anum≥Bnum。
最后把每个质因数的答案max起来即可。
感觉本场比赛没有trick(雾~),我就打算加入一个很经典的trick:
B可以刚好等于263,这样就要开unsigned long long。
同时我还在题目里特别提醒了“注意M的范围”
可惜仍然有很多选手没有注意。
这里我表示歉意,也希望你们以后可以更加仔细一点。
对于题目的解法,我相信通过出题人的解题报告,多多少少都能明白一点,在此,我也不多说,有不明白的可以留下评论在此,其实我想说的是,B的定义问题,因为B可以取到263,所以不管是long long,还是__int64都是不够大的,因为它们所能表示的最大值为263-1,所以就如上面的题解所说要用到unsigned,也就是这个原因,我不小心坑害了3个人
可能是看到我用了__int64吧,他们果断用下面这组数据来hack我
1
2 9223372036854775808
2 9223372036854775808
然而令我也没想到的是居然还是对的,虽然__int64的变量m无法保存263,但是它会保存成-263,这对于求公约数是没有影响的,而我代码中的n不断变大,就算m为-263,n最终也能成-263,这样就保证了可以判断n==m
0 0
- hdu5902,5505——GCD小合集
- hdu5902 GCD is Funny
- hdu5902 GCD is Funny
- hdu5902 GCD is Funny
- HDU5902
- hdu5902 GCD is Funny(错) && hdu5904 LCIS(最长公共连续上升子序列)
- hdu5902暴力
- hdu5902 数论
- GCD实践——GCD延时执行
- GCD实践——GCD线程组
- GCD实践——GCD定时器
- GCD & 拓展GCD 入门——HDU
- 最大公约数——gcd
- 数论——GCD
- 多线程 —— GCD
- 多线程——GCD
- 《多线程——GCD》
- 最大公约数——gcd
- 科锐课堂笔记:2017/4/21 多重继承与智能指针
- 随机梯度下降算法
- Servlet url-pattern /与/*区别,*.action以及SpringMVC中/*解析出错过程分析
- docker_practice从入门到实践总结
- 第五章 5-11 绘图模式
- hdu5902,5505——GCD小合集
- 关于根文件系统 jffs2和ubifs
- Java EE 概述
- 给定一个正整数n,要求找到最小的x(x>0)满足2^x mod n = 1。
- 取消后续内容执行
- C++文件流的建立与关闭
- java—HelloWorld
- MySQL加速查询速度的独门武器:查询缓存
- 呱哩哗啦电脑人安卓版和iOS版发布,试试手机自动写代码