NC21721. 爱摸鱼的Dillonh
描述
“我不做人啦,jojo!”
“Dillonh起来回答问题!”
“啊?”沉迷于jojo的Dillonh又一次上课摸鱼被老师抓到了,他慌忙地抬起头看着讲台上火冒三丈的老师。
“给你一个数n,现在要找到一个集合,中若干数,使得,同时对于任意的i和j()都要满足,你能找到所有满足这个条件的集合吗。如果对于这个数n有无限多个可能的集合,那么就输出-1,否则就输出所有不同的集合。”如果眼神能杀人的话,此刻的Dillonh就已经被他的老师杀了千万遍了。
“这...”沉迷摸鱼的Dillonh自然是不会做这个题的,他现在急的满头大汗。作为聪明的ACMer,你能帮他解决这个问题吗?
(对于两个集合和,如果两个集合内元素的个数不同的话,就认为这两个集合是不同的;如果这两个集合内元素个数相同的话,如果两个集合内的元素不论以任何顺序排序之后,仍然是不完全相同的话,那么就认为这两个集合是不同的)。
输入描述
第一行一个数字T,代表有T组测试样例(T<=100)
对于每组测试样例都会输入一个数字n,代表老师提出的问题的数。()。
输出描述
对于每组测试样例,第一行输出一个“Case #x:”,x代表当前为第几组测试样例。
如果有无限多个满足条件的集合,第二行就输出“-1”;
否则的话,第二行输出一个数字m,代表有m个集合是满足条件的。
接下来m行输出这m个集合的信息,按集合内元素个数的大小从小到大输出,
每行的第一个数num代表集合内元素的个数,接下来按从小到大输出num个数。每行的两个数之间用一个空格隔开,行末不要有空格。
示例1
输入:
2 12 1
输出:
Case #1: 3 1 12 2 3 4 3 2 2 3 Case #2: -1
C++11(clang++ 3.9) 解法, 执行用时: 1536ms, 内存消耗: 620K, 提交时间: 2019-01-30 14:26:56
#include<bits/stdc++.h> using namespace std; int t,ge,l[10010],a,b; long long n,o[10010][100],u,v; int main(){ scanf("%d",&t); for(int i=1;i<=t;i++){ printf("Case #%d:\n",i); scanf("%lld",&n); u=n; while(u%2==0) u/=2; if(u==1){ printf("-1\n"); continue; } l[1]=ge=1; o[1][l[1]]=n; v=u=floor(sqrt(n)); if(u*u==n) l[++ge]=2,o[ge][1]=u,o[ge][2]=u; if(u*(u+1)==n) l[++ge]=2,o[ge][1]=u,o[ge][2]=u+1; for(long long k=1000000;k>=2;k--){ if(k==v||k==n) continue; u=n,a=0,b=0; if(u%k==0){ while(u%k==0) u/=k,a++; while(u%(k+1)==0) u/=(k+1),b++; if(u==1){ l[++ge]=a+b; for(int i=1;i<=a;i++) o[ge][i]=k; for(int i=1;i<=b;i++) o[ge][a+i]=k+1; } } } printf("%d\n",ge); for(int i=1;i<=ge;i++){ printf("%d",l[i]); for(int j=1;j<=l[i];j++){ printf(" %lld",o[i][j]); } printf("\n"); } } return 0; }
C++14(g++5.4) 解法, 执行用时: 12ms, 内存消耗: 628K, 提交时间: 2018-12-29 22:51:17
#include<bits/stdc++.h> using namespace std; using LL=long long; vector<vector<LL>>ans; vector<LL>v; int main() { int T; cin>>T; LL n; int cas=1; LL x; int i; while(T--) { cin>>n; x=n; while((x&1)==0) x>>=1; cout<<"Case #"<<cas++<<":"<<endl; if(x==1) { printf("-1\n"); continue; } for(i=1;i<=63;i++) { LL t=powl(n,1.0/i); if(t<=1) continue; x=n; v.clear(); while(x%t==0) { v.push_back(t); x/=t; } while(x%(t+1)==0) { v.push_back(t+1); x/=t+1; } if(x==1&&v.size()==i) ans.push_back(v); } cout<<ans.size()<<endl; for(const auto&x:ans) { cout<<x.size(); for(const auto&y:x) cout<<' '<<y; cout<<endl; } ans.clear(); } return 0; }