SGU 102 Coprimes
裸的欧拉函数……
暴力搜索也可以过……
(代码写的很水很水很水,不要看!)
欧拉函数版
/************************************************************************* > File Name: sgu102.cpp > Author: Shine > Created Time: 2013-05-04 上午 6:36:05 > QuestionType: 欧拉函数 > Way: > Submit: > Gain: > Experience: ************************************************************************/ #include <cstdio> #include <cstring> #include <cmath> int yz[10010][6] = {0}; void predo() { int i; for (i = 2; i < 10000; i++) { if (yz[i][0] == 0) { int &p = yz[i][0]; yz[i][++p] = i; int j; for (j = 2; i*j<=10000; j++) { int &p = yz[i*j][0]; yz[i*j][++p] = i; } } } } int main() { predo(); int n; while (scanf("%d", &n)!=EOF) { int i; double num = n; for (i = 1; i <= yz[n][0]; i++) { num = num *(1.0-1.0/yz[n][i]); } printf("%.0llf\n", num); } return 0; }
暴力搜索版
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #define min(a,b) ((a)<(b)?(a):(b)) int kgcd(int a, int b){ if (a == 0) return b; if (b == 0) return a; if (!(a & 1) && !(b & 1)) return kgcd(a>>1, b>>1) << 1; else if (!(b & 1)) return kgcd(a, b>>1); else if (!(a & 1)) return kgcd(a>>1, b); else return kgcd(abs(a - b), min(a, b)); } int main() { int n; while(scanf("%d", &n) != EOF) { int i; int num = 1; for (i = 2; i < n; i++) { if (kgcd(i,n) == 1) num++; } printf("%d\n", num); } return 0; }
为什么欧拉函数版本写成这样?因为我AC的思路是:
求出每个数所有因子,然后不可行的个数sum = n/一个因子 - n/ 两个因子数积 + n/ 三个因子的积 - ……
因为输出过,最多5个因子,然后又想不到什么好的写法,所以很暴力的写成了这么多层循环……
因子商 求和 去重版
#include <cstdio> #include <cstring> #include <cmath> int yz[10010][6] = {0}; int re[10010] = {0}; void predo() { int i; for (i = 2; i < 10000; i++) { if (yz[i][0] == 0) { int &p = yz[i][0]; yz[i][++p] = i; int j; for (j = 2; i*j<=10000; j++) { int &p = yz[i*j][0]; yz[i*j][++p] = i; } } } } int main() { predo(); int n; while (scanf("%d", &n)!=EOF) { if (re[n]) printf("%d\n", re[n]); else { int i; int sum = 0; for (i = 1; i <= yz[n][0]; i++) { sum += n/yz[n][i]; } int j; for (i = 1; i <= yz[n][0]-1; i++) { for (j = i+1; j <= yz[n][0]; j++) { sum -= n / (yz[n][i]*yz[n][j]); } } int k; for (i = 1; i <= yz[n][0]-2; i++) { for (j = i+1; j <= yz[n][0]-1; j++) { for (k = j+1; k <= yz[n][0]; k++) { sum += n/(yz[n][i]*yz[n][j]*yz[n][k]); } } } int l; for (i = 1; i <= yz[n][0]-3; i++) { for (j = i+1; j <= yz[n][0]-2; j++) { for (k = j+1; k <= yz[n][0]-1; k++) { for(l = k+1; l <= yz[n][0]; l++) { sum -= n/(yz[n][i]*yz[n][j]*yz[n][k]*yz[n][l]); } } } } if (yz[n][0] == 5) sum += n/(yz[n][1]*yz[n][2]*yz[n][3]*yz[n][4]*yz[n][5]); printf("%d\n", re[n]=n-sum); } } return 0; }
对于这种式子,不知道有没有人有更好的写法。。有的话请留个练习方式或者评论回复我都可以~感谢哦~
posted on 2013-05-05 21:54 ShineCheng 阅读(185) 评论(0) 编辑 收藏 举报