首页 > 代码库 > UVALive - 7638
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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。