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;
    }

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

  • 相关阅读:
    .net core实现的全程序跟踪
    gmap.net
    Spring Cloud实践:降级、限流、滚动、灰度、AB、金丝雀的实现思路
    服务的协作:服务间的消息传递——《微服务设计》读书笔记
    使用消息系统进行微服务间通讯时,如何保证数据一致性
    How to distribute a database among microservices
    微服务间如何选择推送和拉取数据
    Android 怎么使用Bitmap+Canvas 自适应屏幕
    Android 音乐播放器之--错误状态下调用导致的异常
    Android应用截图和SurfaceView截图问题总结
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3061593.html
Copyright © 2011-2022 走看看