UVALive - 7638
Posted 发牌员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive - 7638相关的知识,希望对你有一定的参考价值。
这个题有点复杂,当时有思路,就是不知道怎么写,看了大佬的代码,思考了很长时间。。。。。。这里就是先打表把每个数字的公因数存一个数组,然后以给的a[i]为大哥和他的公因数建树,再以,a[i]为小弟看有没有在树的大哥,这里想不到
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn=1000000+5; int pre[maxn],flag[maxn],a[maxn]; int t,n,ans; vector<int> aa[maxn]; int find(int x) { if(pre[x]==x) return x; else return pre[x]=find(pre[x]); } void init() { for(int i=1;i<=maxn;i++) pre[i]=i; } void unit(int x,int y) { x=find(x); y=find(y); if(x==y) return; if(x>y) pre[x]=y; else pre[y]=x; } void haha() { for(int i=2;i<maxn;i++) for(int j=i;j<maxn;j+=i) aa[j].push_back(i);//把j的公因数成数组 } int main() { haha(); scanf("%d",&t); for(int zz=1;zz<=t;zz++) { ans=0; init(); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); for(int j=0;j<aa[a[i]].size();j++) unit(a[i],aa[a[i]][j]);//先以a[i]为大哥,使他的小弟,也就是所有公因数指向他 } memset(flag,0,sizeof(flag)); for(int i=0;i<n;i++) {//再以a[i]为小弟,去寻找他的大哥 int root=find(a[i]);//寻找出现过的a[i]的结点 if(flag[root]==0)//没有被访问过,如果被访问过就不能加组数了 { ans++;//组数增加 if(a[i]!=1)//1很特别,反正他的节点是自己,自成一组 flag[root]=1;//访问过,标记 } } printf("Case %d: %d\n",zz,ans); } return 0; }
以上是关于UVALive - 7638的主要内容,如果未能解决你的问题,请参考以下文章
UVALive 3971 Assemble(模拟 + 二分)
UVALive 4726 Average ——(斜率优化DP)
UVALive 4670 Dominating Patterns