您的位置:首页 > 其它

POJ 2773 欧拉函数, 素数表

2012-08-06 10:48 225 查看
这题很很很不懂,谁能详细讲解下。

素数表第一次用,用了不熟练,欧拉函数求了好久出来,不太懂。

#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAXN 1000010
int prime[MAXN], phi[MAXN];
void Init()
{
int i, j, k = ceil(sqrt(1000010));
//求素数表
memset(prime, 0, sizeof(prime));
prime[0] = prime[1] = 1;
for (i = 2; i < k; i++)
{
if (prime[i] == 0)
{
for (j = 2 * i; j < MAXN; j += i)
prime[j] = 1;
}
}
//求欧拉函数值
for (i = 1; i < MAXN; i++)
phi[i] = i;
for (i = 2; i < MAXN; i++)
{
if (prime[i] == 0)
{
for (j = i; j < MAXN; j += i)
//phi(n) = n * (1 - 1/p1) * (1 - 1/p2)....[pi是与n的质因素]
phi[j] = phi[j] / i * (i - 1);
}
}
}
int GCD(int a, int b)
{
int t;
while (b)
{
t = b;
b = a % b;
a = t;
}
return a;
}
int main()
{
int m, K, cnt, i, flag, mul;
Init();
while (scanf("%d%d", &m, &K) != EOF)
{
//判断m内第几个与m互素
cnt = K % phi[m];
//判断分为了几组
mul = K / phi[m];
//正好分为整数组
if (cnt == 0)
{
//m的最后一个与其互素的
cnt = phi[m];
//分组减一
mul--;
}
flag = 0;
for (i = 1; i < m; i++)
//判断是否互素
if (GCD(m, i) == 1)
{
flag++;
if (flag == cnt)
break;
}
//printf("phi[m] = %d i = %d mul = %d\n", phi[m], i, mul);
printf("%d\n", mul * m + i);
}
return 0;
}
这个是我第n次RE后写的,超时了,有什么特别好的优化方法吗? 请教下大家

#include <stdio.h>
int Coprime (int a, int b)
{
int t;
while (b)
{
t = b;
b = a % b;
a = t;
}
if (a == 1)
return 1;
return 0;
}
int main()
{
int i, m, cnt, K, flag, phi_m, mul;
while (scanf("%d%d", &m, &K) != EOF)
{
phi_m = flag = 0;
for (i = 1; i <= m; i++)
if (Coprime(m, i))
phi_m++;
cnt = K % phi_m;
mul = K / phi_m;
if (cnt == 0)
{
cnt = phi_m;
mul--;
}
for (i = 1; i <= m;  i++)
if (Coprime(m, i))
{
flag++;
if (flag == cnt)
break;
}
printf("%d\n", mul * m + i);
}
return 0;
}


今天又练了到素数表的题, 不过时间好慢200+MS 不知道别人的0MS怎么弄出来的

有谁知道怎么优化比较好, 发个链接, 谢谢。

POJ 3006 筛素数

#include <stdio.h>
#include <string.h>
int prime[1000010];
void init()
{
int i, j;
memset(prime, 0, sizeof(prime));
prime[0] = prime[1] = 1;
for (i = 2; i < 1000; i++)
{
if (prime[i] == 0)
for (j = 2 * i; j < 1000000; j += i)
prime[j] = 1;
}
}
int main()
{
int a, d, n, num, i;
init();
while (scanf("%d %d %d", &a, &d, &n) != EOF)
{
if (!(a || d || n)) break;
num = i = 0;
while (num != n)
{
if (prime[a + i * d] == 0) num++;
i++;
}
printf("%d\n", a + (i - 1) * d);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: