您的位置:首页 > 移动开发

poj 2773 Happy 2006

2016-06-03 08:34 316 查看
题意:求出第k个与m互质的数

方法一:

暴力求解:gcd应用

#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 1000005
using namespace std;
int pri[MAXN];
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
int m,k;
while(cin >>m>>k)
{
int i,j,ans;

for(i=1,j=0;i<=m;i++)
{
if(gcd(i,m)== 1)
pri[j++] = i;
}
if(k%j!=0)
ans =k/j*m+pri[k%j-1];
else
ans = (k/j-1)*m+pri[j-1];
cout << ans <<endl;

}
return 0;
}
方法二:
欧拉函数求解
/*
runtime:63ms
*/
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1000005
using namespace std;
vector <int> pp;
int prime[1005];
bool flag[1005];
bool IsCoprime[maxn];
int Num_prime;
void Eular()
{
int i,j;
for (i=2; i<1001; i++)
{
if (!flag[i])
{
prime[Num_prime++]=i;
}
for (j=0; (j<Num_prime)&&(i*prime[j]<1001); j++)
{
flag[i*prime[j]]=true;
if (i%prime[j]==0)
{
break;
}
}
}
}

int Eularfunction(int n) //即求phi(n)
{
int res=n;
int n_orign=n;
for (int i=0; i<Num_prime; i++)
{
if (n%prime[i]==0)
{
res=res/prime[i]*(prime[i]-1);
while (n%prime[i]==0)
{
n=n/prime[i];
}
for (int k=prime[i]; k<=n_orign; k+=prime[i])
{
IsCoprime[k]=false;
}
if (n==1)
{
break;
}
}
}
if (n!=1)
{
res=res/n*(n-1);
for (int k=n; k<=n_orign; k+=n)
{
IsCoprime[k]=false;
}
}
return res;
}

void solve(int m)
{
pp.clear();
pp.push_back(1);
for(int i=2;i<m;i++)
{
if(IsCoprime[i])
{
pp.push_back(i);
}
}
}

int main()
{
int m,k;
Eular();
while (~scanf("%d %d",&m,&k))
{
memset(flag,false,sizeof(flag));
memset(IsCoprime,true,sizeof(IsCoprime));
int res;
if(m==1)
{
printf("%d\n",k);
}
else
{
int phi=Eularfunction(m);
solve(m);
if(k%phi!=0)
{
res=k/phi*m+pp[k%phi-1];
}
else
{
res=(k/phi-1)*m+pp[phi-1];
}
printf("%d\n",res);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: