算法竞赛入门经典第2版 第2章 循环结构

学习目标

  掌握for循环、while循环、do-while循环的使用方法

  学会使用计数器和累加器

  学会用输出中间结果的方法调试

  学会用计时函数测试程序效率

  学会用重定向、fopen的方式读写文件

  了解算法竞赛对文件读写方式和命名的严格性

  记住变量在赋值之前的值是不确定的

  学会使用条件编译指示构建本地运行环境

  学会用编译选项-Wall获得更多的警告信息

                                                                                                                                2.1 for循环
例2-1 aabb

#include <stdio.h>

int main()
{
    /* 方法一
    int i,j,m,n;
    for(i=1;i<10;i++)
    {
        for(j=0;j<10;j++)
        {
            m = i*1100+j*11;
            n = floor(sqrt(m)+0.5);   //浮点运算可能存在误差,为了减小误差的影响,所以加上0.5,以便四舍五入。
            if(n*n == m)
            {
                printf("%d\n",m);
            }
        }
    }*/

    //方法二:枚举平方根,从而避免开平方操作
    int i,n,a,b;
    for(i=1;;i++)
    {
        n = i*i;
        if(n>10000)
        {
            break;
        }
        if(n<1000)
        {
            continue;
        }
        a = n/100;
        b = n%100;
        if(a/10 == a%10 && b/10 == b%10)
        {
            printf("%d\n",n);
        }
    }

    return 0;
}

                                                                                                                           2.2 while循环和do-while循环
例2-2 3n+1问题

#include <stdio.h>

int main()
{
    int n,count = 0;
    scanf("%d",&n);
    long long n1 = n;   //int为32位的,long long为64位的,但它的输入输出比较复杂
    while(n1>1)
    {
        if(n1%2 != 0)
        {
            n1 = 3*n1+1;
        }else{
            n1 = n1/2;
        }
        count++;
    }

    printf("%d\n",count);
    return 0;
}
/* 1.注意乘法溢出的问题
2.long long型

例2-3 近似计算

#include <stdio.h>

int main()
{
    int i;
    double sum = 0,term;

    for(i=0;;i++)
    {
        term = 1.0/(2*i+1);  //注意应用1.0,使能够算出来浮点数
        if(i%2 == 0)
            sum += term;
        else
            sum -= term;
        if(term<1e-6)
            break;
    }
    printf("%f\n",sum);
    return 0;
}

 2.3 循环的代价

例2-4 阶乘之和

#include <stdio.h>
#include <time.h>

int main()
{
    const int MOD = 1000000;
    int n,i,a=1,b,sum=0;
    scanf("%d",&n);

    for(i=1;i<=n;i++)
    {
        a *= i;
        b = a%MOD;
        sum += b;
    }
    printf("%d\n",sum);
    printf("Time used = %.2f\n",(double)clock() / CLOCKS_PER_SEC);
    return 0;
}
/*  1.clock()函数返回程序目前为止运行的时间。常数CLOCK_PER_SEC和操作系统有关,不要直接使用clock()的返回值,而应总是除以这个常数。
    2.上述得出的时间包括了键盘输入的时间。为了避免输入数据的时间影响测试结果,是使用一种称为“管道"的小技巧。
    3.尝试很多次之后发现,从第五项开始,后面所有的项都不会影响和的末六位数字,所以只需在最前面加上“if(n>5) n=25;"
      效率和溢出都不会存在问题。

例2-5 数据统计

#include <stdio.h>
#define N 1000000

int main()
{
    int max=-N,min=N,a,sum=0,i=0;
    while(scanf("%d",&a) == 1)
    {
        sum += a;
        if(a<min)
            min = a;
        if(a>max)
            max = a;
        i++;
    }
    printf("%d %d %.3f\n",max,min,(double)sum/i);
    retnrn 0;
}
    
    
    //重定向版
#define LOCAL
#include <stdio.h>
#define N 1000000

int main()
{
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif // LOCAL
    
    int max=-N,min=N,a,sum=0,i=0;
    while(scanf("%d",&a) == 1)
    {
        sum += a;
        if(a<min)
            min = a;
        if(a>max)
            max = a;
        i++;
    }
    printf("%d %d %.3f\n",max,min,(double)sum/i);
    return 0;
}

    //fopen版
#include <stdio.h>
#define N 1000000

int main()
{
    FIFE *fin,*fout;
    fin = fopen("data.in","rb");
    fout = fopen("data.out","wb");
    
    int max=-N,min=N,a,sum=0,i=0;
    while(fscanf(fin,"%d",&a) == 1)
    {
        sum += a;
        if(a<min)
            min = a;
        if(a>max)
            max = a;
        i++;
    }
    fprintf(fout,"%d %d %.3f\n",max,min,(double)sum/i);
    fclose(fin);
    fclose(fout);
    return 0;
}

/* 1.输入数据,按enter键,并未显示结果,不是程序运行太慢,而是仍在等待输入。在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,
     最后再按Enter键即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。
   2.使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加上以下两条语句:
     freopen("input.txt","r",stdin);
     freopen("output.txt","w",stdout);
   3.如果比赛要求用文件输入输出,但禁止使用重定向的方式,则可以使用fopen。
   4.重定向和fopen两种方法各有优劣。
     重定向:写起来自然、简单,但是不能同时读写文件和标准输入输出。
     fopen:写法稍显繁琐,但是灵活性比较大(例如,可以反复打开并读写文件)。如果想把fopen版的程序改成读写标准输入输出,
            只需赋值"fin=stdin;fout=stdout;"即可,不要调用fopen和fclose。
*/


例2-6 数据统计II

#include <stdio.h>
#define N 10000000

int main()
{
    int n,a,k=0,i,max=-N,min=N,sum;
    while(scanf("%d",&n) == 1 && n)
    {
        max=-N,min=N;
        sum = 0;
        for(i=0;i<n;i++)
        {
            scanf("%d",&a);
            sum += a;
            if(a>max)
                max = a;
            if(a<min)
                min = a;
        }
        if(k)
            printf("\n");
        printf("Case %d: %d %d %f\n",++k,min,max,(double)sum/n);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ljlzl/p/10085933.html