zoukankan      html  css  js  c++  java
  • AOJ.综合训练.2016-12-1

    友情提示:不要复制粘贴,看完解析先自己尝试写一下,不行再看代码!祝AC愉快 @_@

    A. 近似值计算

    题意分析

    根据公式,先用含有n的代数式表示出来pi,然后计算这个近似值和题目给出来的3.14159165作差求绝对值,当差值大于1e-5的时候继续计算,否则就跳出循环输出。
    有几点需要注意的,首先做除法预算的时候(题目中的n),要为double类型,如果为int类型的话最后结果为0。还有注意题目中的初始条件,即在声明变量的时候所初始化的值。

    #include <stdio.h>
    #include <math.h>
    int main()
    {
        int i = 1;
        double pi = 3.14159165,ret = 1,temp = 1;
        while(fabs(ret-3.14159165)>=1e-5){
            i++;
            double j = i;
            temp+= 1/(j*j);
            double temp1 = temp *6;
            ret = sqrt(temp1);
    
        }
        printf("%d
    ",i);
        return 0;
    }
    

    当然还有一种比较NB的写法。
    因为,这题的结果是个常数。

    #include <stdio.h>
    int main()
    {
        printf("86784
    ");
        return 0;
    }
    

    B. 多重素因子

    题意分析

    这题和期中考试最后一道程序题有相似之处。输出他们的因子,如果是负数的话,先输出-1,然后输出他的因子。(这题就是分解质因数?)

    上次AOJ16级兴趣赛有个分解质因数的题。结合了上次打素数表的方法,可以学习一下。

    以下是分解质因数的代码,不是此题AC代码。

    #include <stdio.h>
    #include <stdlib.h>
    #define max 100001
    int a[max];//0是素数,1是非素数
    
    int main()
    {
        int i,j;
        for(i =2;i<max;i++ ){
            for(j = 2;i*j<=max;j++){
                a[j*i] = 1;
            }
        }
    
        int n;
        while(scanf("%d",&n) != EOF&&n){
            int flag = 0,temp;
            if(a[n] == 0){
                printf("%d=%d
    ",n,n);
            }else{
                temp = n;
                for(i =2 ;i<temp;i++){
    
                    while(n%i == 0){
                        if(!flag){
                            printf("%d=%d",n,i);
                            flag = 1;
                        }else{
                            printf("*%d",i);
                        }
                        n = n/i;
                    }
                    if(n == 1){
                        break;
                    }
                }
                printf("
    ");
            }
        }
        return 0;
    }

    当然打素数表优点就是用空间换取时间,不用多次循环判断素数。
    那么这题也可以用暴力方法。就是对于i∈[2,N]循环判断,如果这个i能整除N,那么i即为N的因子,输出i并使N=N/i,循环上述判断流程,直到N=1为止。
    下面给出AC代码,中间有几个变量多余了,还有优化的余地,大家可以试着优化一下.

    #include <stdio.h>
    #include <math.h>
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            int i;
            if(n<0){
                printf("-1 ");
                n = -n;
            }
            int temp = n;
            for(i = 2;i<=n;i++){
                if(temp == 1){
                    break;
                }else{
                    if(temp%i == 0){
                        int ret;
                         ret = temp;
                        while(ret){
                            if(ret%i == 0){
                                ret/=i;
                                printf("%d ",i);
                            }else{
                                break;
                            }
                        }
                        temp = ret;
                    }
    
                }
            }
            printf("
    ");
        }
        return 0;
    }
    

    C. 函数值计算

    题意分析

    这题好坑啊。一开始怎么算都算不出样例给出的记过,后来汪神说是题目错了,按正确做法改了发现的确是题目错了。
    首先观察题目给出来的多项式,x的系数分别为1,3,5,7……奇数次项,而且x^n下面还除了一个n。前边的系数,第一项是1,第二项1/2,第三项1 *3 *5/(2 *4 *6)不难发现,分子是奇数的乘积,分母是偶数的乘积,而且x的系数是奇数次增长。都带有一定规律那么就可以用循环来做。关键是,要循环到多少次,最后算出的小数才和样例一样。
    这个大家写好程序,试着调试一下就就好了。下面有一点需要注意的:分母在计算时一律转化成double,否则最后就会发现无论循环次数怎么增加,结果都不变,原因就是算完之后结果为0,无论和结果如何累加,最后都是+0。(一开始我也不知道怎么回事,卡了半天)

    #include <stdio.h>
    #include <math.h>
    double get(double x,int n)
    {
        double temp = x;
        n--;
        while(n--){
            x = x*temp;
        }
        return x;
    }
    int main()
    {
       int t;
       double x,ret = 0;
       scanf("%d",&t);
       while(t--){
        scanf("%lf",&x);
        ret = 0;
        int i = 1;
        double up = 1,up1 = 1;
        double down = 2,down1 = 2;
        int sgn = 1;
        while(i<=200){
            if(i == 1){
                ret+=x;
            }else{
                ret= ret+ 1.0* sgn* up/(down*1.0*i) * get(x,i);
                up1+=2;
               down1+=2;
               up=up*up1;
            down=down*down1;
            }
    
            sgn = -sgn;
            i+=2;
        }
    
        printf("%f
    ",ret);
       }
        return 0;
    }
    

    D. 完全数

    题意分析

    这题比较裸,直接写个大循环算就行好了。
    因子的计算,正好可以用到上面B题的思路。直接来代码吧。

    #include <stdio.h>
    #include <math.h>
    int main()
    {
       int i ;
       printf("1
    ");
       for(i = 2;i<=1000;i++){
        int ret = 0,j;
        for(j = 1;j<i;j++){
            if(i%j == 0){
                ret +=j;
            }
        }
        if(ret == i){
            printf("%d
    ",i);
        }
       }
        return 0;
    }
    

    当然这题结果固定,也可以这么干。

    #include <stdio.h>
    int main()
    {
        printf("1
    6
    28
    496
    ");
        return 0;
    }
    

    E. 元音,辅音

    题意分析

    题面理解起来不难。这题有坑。首先是多组输入输出。题干已经告诉了,字符串中没有空格,所以用gets和scanf(%s)都可以。然后处理字符串,首先判断是否是元音字母,是的话原因计数器+1,否则的话,判断是否是字母(大写和小写都包括),如果是的话,辅音计数器+1(因为这题有别的字符,比如标点斜杠等等)。别忘了在每组数据读取后,要初始化计数器。

    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    int main()
    {
        int cnt1,cnt2;
        char str[1000];
        while(gets(str)){
            cnt1 = cnt2 = 0;
            int i;
            for(i = 0;i<strlen(str);i++){
                if(str[i] == 'a' || str[i] == 'e'|| str[i]=='i' || str[i] =='o' || str[i] == 'u' || str[i] == 'A'||str[i] == 'E' || str[i] == 'I' || str[i] == 'O'|| str[i] == 'U'){
                    cnt1++;
                }else if((str[i]>='a' && str[i] <='z') || (str[i]>='A' && str[i]<='Z')){
                    cnt2 ++;
                }
            }
            printf("%d %d
    ",cnt1,cnt2);
        }
        return 0;
    }

    F. 整数移位 1

    题意分析

    这题用字符串写比较简单,就是一个字符串某个字符的交换。如果用数组的话,还要反复/10,%10比较麻烦,不如字符串。

    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    int main()
    {
        char str1[500],str2[500];
        int n,p;
        scanf("%s",str1);
        scanf("%d %d",&p,&n);
        scanf("%s",str2);
        char temp;
        int len1 = strlen(str1);
        int len2 = strlen(str2);
        int i;
        for(i = 0;i<n;i++){
            temp =  str1[p-1+i];
            str1[p-1+i] = str2[len2-1-i];
            str2[len2-1-i] = temp;
        }
        printf("%s
    ",str1);
        return 0;
    }
    
  • 相关阅读:
    子网掩码
    linux中grep工具
    C#尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
    c#常用的Datable转换为json,以及json转换为DataTable操作方法
    easyui-从数据库读取创建无极菜单
    wpf 进度条 下拉
    进度条与执行过程
    属性表格 datagridproperty
    Jquery easyui开启行编辑模式增删改操作
    asp.net (jquery easy-ui datagrid)通用Excel文件导出(NPOI)
  • 原文地址:https://www.cnblogs.com/pengwill/p/7367191.html
Copyright © 2011-2022 走看看