zoukankan      html  css  js  c++  java
  • 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;
    }

    对于这种式子,不知道有没有人有更好的写法。。有的话请留个练习方式或者评论回复我都可以~感谢哦~

  • 相关阅读:
    mac 卸载 node并重新安装
    最小的Django应用
    Python如何实现文本转语音
    Python语言库pyttsx3
    大数据资料
    剑指offer(29)最小的K个数
    剑指offer(28)数组中出现次数超过一半的数
    剑指offer(27)字符串的排列
    剑指offer(26)二叉搜索树与双向链表
    JS、JAVA刷题和C刷题的一个很重要的区别
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3061593.html
Copyright © 2011-2022 走看看