sgu 499 Greatest Greatest Common Divisor 约数“打表”
来源:互联网 发布:京东商城javaweb源码 编辑:程序博客网 时间:2024/05/21 19:41
题目地址: http://acm.sgu.ru/problem.php?contest=0&problem=499
分析思路: 直接计算两两的最大公约数会超时的,我们换个角度看问题,我们找到输入进来的数的所有约数,如果某个数出现了两次或者以上,那么满足条件的最大的就是ggcd了
然后就是类似于筛法找约数, 这样可以找到 1~n中,每个数不超过自己平方根的所有约数。 然后比平方根大的那个可以用它除出来(完全平方数要特判了)。
然后不是暴力直接从最大的开始找出现过两次的,我们设置一个maxn来记录就好了,每次第二次出现的数和maxn比较一下就可以了。
先看代码:
#include<iostream>#include<vector>#include<cmath>//#include<cstdio>using namespace std;#define N 1000005vector<int> v[N+1];//int cnt[N+1]={0};bool b[N+1]={0};void pre(){ int len=sqrt(N); for(int i=1;i<=len;i++) for(int j=i*i;j<=N;j+=i) v[j].push_back(i);}int maxn=1;void check(int n){ if(b[n]) { maxn=n>maxn?n:maxn; } b[n]=1;}int main(){ pre(); int size; cin>>size; for(int i=0;i<size;i++) { int n; cin>>n; if(n<=maxn) continue; for(int j=0;j<v[n].size();j++) { check(v[n][j]); if(v[n][j]*v[n][j]!=n) check(n/v[n][j]); }// int sqrtn=sqrt(n);// for(int j=1;j<=20&&j<=sqrtn;j++)// {// if(n%j==0)// { check(j);//// if(j*j!=n) check(n/j);//// }// } }// for(int i=1000000;i>0;i--)// if(cnt[i]>=2)// {// cout<<i<<endl;// break;// } cout<<maxn<<endl; }
这个是会超时的,因为每个数都有因子1,一般的数有因子2,我们在打表的时候选择不打前20个约数,然后针对输入进来的数(毕竟只有10w个少于数据范围100w),前20个检查一下就好了。
然后是,sqrt(n)不要出现在for(int i=0;i,<sqrt(n);i++) 这里, 先计算出来 ,不然每次判断都会去计算。 因为这个tle了几次。
在总是tle卡在test 20时 ,把所有cin cout 改成了scanf printf ,可以跑到test 38 还是改进皮毛呀
最后艰难ac了,代码:
#include<iostream>#include<vector>#include<cmath>//#include<cstdio>using namespace std;#define N 1000005vector<int> v[N+1];//int cnt[N+1]={0};bool b[N+1]={0};void pre(){ int len=sqrt(N); for(int i=21;i<=len;i++) for(int j=i*i;j<=N;j+=i) v[j].push_back(i);}int maxn=1;void check(int n){ if(b[n]) { maxn=n>maxn?n:maxn; } b[n]=1;}int main(){ pre(); int size; cin>>size;// scanf("%d",&size); for(int i=0;i<size;i++) { int n; cin>>n; // scanf("%d",&n); if(n<=maxn) continue; for(int j=0;j<v[n].size();j++) { check(v[n][j]); if(v[n][j]*v[n][j]!=n) check(n/v[n][j]); } int sqrtn=sqrt(n); for(int j=1;j<=20&&j<=sqrtn;j++) { if(n%j==0) { check(j); if(j*j!=n) check(n/j); } } }// for(int i=1000000;i>0;i--)// if(cnt[i]>=2)// {// cout<<i<<endl;// break;// } cout<<maxn<<endl; // printf("%d\n",maxn);}
- sgu 499 Greatest Greatest Common Divisor 约数“打表”
- SGU 499:Greatest Greatest Common Divisor
- Greatest Greatest Common Divisor
- sgu 499. Greatest Greatest Common Divisor(枚举因子)
- Greatest Greatest Common Divisor HD5207
- Greatest common divisor
- The Greatest Common Divisor
- GCD (Greatest Common Divisor)
- Solving Greatest Common Divisor
- the greatest common divisor
- 最大公约数Greatest Common Divisor
- HDU 5207 Greatest Greatest Common Divisor
- 【瞎搞】 HDU 5207 Greatest Greatest Common Divisor
- Greatest Greatest Common Divisor hdu 5207
- hdu 5207 Greatest Greatest Common Divisor
- hdu 5207 Greatest Greatest Common Divisor
- HDU 5207 Greatest Greatest Common Divisor
- HDU 5207Greatest Greatest Common Divisor
- 集合框架源码分析三(实现类篇ArrayList,LinkedList,HashMap)
- 集合框架源码分析四(Collections类详细分析)
- 集合框架源码分析五之LinkedHashMap,LinkedHashSet
- 集合框架源码分析六之堆结构的实现(PriorityQueue)
- 13暑假集训#10 总结
- sgu 499 Greatest Greatest Common Divisor 约数“打表”
- HashMap的实现与优缺点
- Tubro C < README 文件>
- 算法稳定性
- 记录一下八款开源 Android 游戏引擎
- 时间复杂度
- (转载)Unity3d事件函数
- 主成分分析(Principal components analysis)-最大方差解释
- linux C++:c++流操作----->rdbuf()