uva 10837 A Research problem 欧拉函数+暴力

来源:互联网 发布:电脑桌面知乎 编辑:程序博客网 时间:2024/06/03 20:30

点击打开链接

m=phi(n)=p1^a1-1(p1-1).....pn^an-1(pn-1)

n中的所有素因子p必须满足m%(p-1)==0这一条件。因此可以事先将所有这样的素数找出来,然后在这些素数的基础上进行暴力搜索

#include <iostream>#include <algorithm>#include <cstring>#include <map>#include <cmath>#include <vector>using namespace std;const int N=1e4;int vis[N+20],pri[N+20],fac[N+20],pn=0,num,ans;void get_prime(){memset(vis,0,sizeof(vis));for(int i=2;i<=N;i++){if(!vis[i]){pri[pn++]=i;for(int j=i+i;j<=N;j+=i){vis[j]=1;}}}}void factor(int m){ans=3e8;num=0;for(int i=0;i<pn&&(pri[i]-1)*(pri[i]-1)<=m;i++){if(m%(pri[i]-1)==0){fac[num++]=pri[i];//cout<<pri[i]<<' ';}}}bool judge(int x){for (int i = 0; i < pn && pri[i] * pri[i] <= x; i++)      if (x % pri[i] == 0) return false; //x不是素数 for(int i=0;i<num;i++){if(fac[i]==x&&vis[i])return false;}return true;}//在这些素数的基础上进行暴力搜索,来枚举哪些素数用与不用。如果用了,//还要枚举所有的合法的使用次数。这看上去时间复杂度会比较高,但实际上每次多乘一个p,对应的值是呈指数上升的,因此能够很快找到解。void dfs(int cur,int f,int m){//cout<<m<<endl;if(cur==num){ if(m==1){//cout<<f<<' ';ans=min(ans,f);}else if(judge(m+1))//最后要单独判断最后一个数是否为素数,而且是没有被使用过的素数{//m/(m+1-1)=1f*=(m+1);ans=min(ans,f);}return;}dfs(cur+1,f,m);//不选该素因子if(m%(fac[cur]-1))//非法 return;vis[cur]=1;//phi(p^aj)=p^aj-p^(aj-1)=p^(aj-1)(p-1) m/=(fac[cur]-1);//选一次 f*=fac[cur];dfs(cur+1,f,m); while(m%fac[cur]==0){m/=fac[cur];//选多次  f*=fac[cur];dfs(cur+1,f,m);}vis[cur]=0;}int main(){get_prime();int cas=0;int m;while(cin>>m&&m){memset(vis,0,sizeof(vis));factor(m);dfs(0,1,m);printf("Case %d: %d %d\n",++cas,m,ans);}return 0; } 


0 0
原创粉丝点击