紫书第二章-----循环结构程序设计

文章内容主要参考刘汝佳著作《算法竞赛入门经典》(第2版)

阶乘之和(了解命令行)

输入n,计算S=1!+2!+3!+……+n!的末6位(不含前导0)。n<=1e6
样例输入
10
样例输出
37913

代码示范:

#include<iostream>
#include<ctime>
#include<cstdio>
using namespace std;

const int mod=1e6;

void solve(int n)
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        int factorial=1;
        for(int j=1;j<=i;j++)
            factorial=factorial*j%mod;
        sum=(sum+factorial)%mod;
    }
    cout<<sum<<endl;
    //printf("Time used = %.2lf\n",(double)clock()/CLOCKS_PER_SEC);
}

int main()
{
    int n;
    while(cin>>n)
    {
        solve(n);
    }
    return 0;
}

本题如果直接不采用每次计算都模的方式,会超时,采用如上写法比较好,不会超时,另外上述算法可以改进的是,由于25!末6位全部是0,所以可以在solve函数第一句增加if(n>25)n=25;这样就优化了代码!

【补充计算程序运行时间的函数及命令行运行程序方式】
其中,注释掉的部分printf(“Time used = %.2lf\n”,(double)
clock()/CLOCKS_PER_SEC);这个可以输出程序运行的时间(包括从键盘输入用时),利用管道echo命令输入(利用命令行运行程序,可以先把.exe文件放在比较好找的目录里,本演示用的.exe文件名称是2017-6-30),则不包括输入数据的用时。下面演示管道输入方法(先在“开始”那里输入“cmd”,回车):

这里写图片描述

注意:如果不适用echo命令,而直接使用命令行输入.exe的名称,再运行程序,这和一般用编译器运行程序是一样的,是包含输入数据的用时的,效果如下:
这里写图片描述

freopen及fopen

题目:输入一些整数,求出他们的最小值、最大值和平均值(保留3位小数)。
样例输入:
2 8 3 5 1 7 3 6
样例输出:
1 8 4.375

代码一(freopen重定向版本):
(如果比赛不允许使用重定向版本,则提交代码前删除#define LOCAL即可)

#include<iostream>
#include<algorithm>
#include<cstdio>
#define LOCAL
using namespace std;

const int maxn=0x3f3f3f3f;

int main()
{
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif //LOCAL

    int x;
    int num=0;;
    int mmin=maxn,mmax=-maxn,ave=0;
    while(cin>>x)
    {
        num++;
        mmin=min(mmin,x);
        mmax=max(mmax,x);
        ave+=x;
    }
    cout<<mmin<<" "<<mmax<<" ";
    printf("%.3lf\n",(double)ave/num);
    return 0;
}

代码二(fopen版):

#include<iostream>
#include<algorithm>
#include<cstdio>
#define LOCAL
using namespace std;

const int maxn=0x3f3f3f3f;

int main()
{
    FILE *fin,*fout;
    fin=fopen("input.txt","r");
    fout=fopen("output.txt","w");
    int x;
    int num=0;;
    int mmin=maxn,mmax=-maxn,ave=0;
    while(fscanf(fin,"%d",&x)==1)
    {
        num++;
        mmin=min(mmin,x);
        mmax=max(mmax,x);
        ave+=x;
    }
    fprintf(fout,"%d %d %.3lf\n",mmin,mmax,(double)ave/num);
    fclose(fin);
    fclose(fout);
    return 0;
}

注:要想把上面代码二改为标准输入输出,直接fin=stdin,fout=stdout即可。

水仙花数 V2 51Nod - 1016

水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3 + 3^3 = 153,1634 = 1^4 + 6^4 + 3^4 + 4^4)。
给出一个整数M,求 >= M的最小的水仙花数。
Input
一个整数M(10 <= M <= 10^60)
Output
输出>= M的最小的水仙花数,如果没有符合条件的水仙花数,则输出:No Solution
Sample Input
300
Sample Output
370

AC代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;

int main()
{
    string s[100] =
    {
        "153","370","371","407","1634",
        "8208","9474","54748","92727","93084","548834","1741725","4210818","9800817","9926315",
        "24678050","24678051","88593477","146511208","472335975","534494836","912985153",
        "4679307774","32164049650","32164049651","40028394225","42678290603","44708635679",
        "49388550606","82693916578","94204591914","28116440335967","4338281769391370",
        "4338281769391371","21897142587612075","35641594208964132","35875699062250035",
        "1517841543307505039","3289582984443187032","4498128791164624869","4929273885928088826",
        "63105425988599693916","128468643043731391252","449177399146038697307",
        "21887696841122916288858","27879694893054074471405","27907865009977052567814",
        "28361281321319229463398","35452590104031691935943","174088005938065293023722",
        "188451485447897896036875","239313664430041569350093","1550475334214501539088894",
        "1553242162893771850669378","3706907995955475988644380","3706907995955475988644381",
        "4422095118095899619457938","121204998563613372405438066","121270696006801314328439376",
        "128851796696487777842012787","174650464499531377631639254","177265453171792792366489765",
        "14607640612971980372614873089","19008174136254279995012734740",
        "19008174136254279995012734741","23866716435523975980390369295",
        "1145037275765491025924292050346","1927890457142960697580636236639",
        "2309092682616190307509695338915","17333509997782249308725103962772",
        "186709961001538790100634132976990","186709961001538790100634132976991",
        "1122763285329372541592822900204593","12639369517103790328947807201478392",
        "12679937780272278566303885594196922","1219167219625434121569735803609966019",
        "12815792078366059955099770545296129367","115132219018763992565095597973971522400",
        "115132219018763992565095597973971522401"};
    string str;
    while(cin>>str)
    {
        bool flag=0;
        for(int i=0;i<79;i++)
        {
            int len1=s[i].length();
            int len2=str.length();
            if(len1>len2 || (len1==len2 && s[i].compare(str)>=0))
            {
                cout<<s[i]<<endl;
                flag=1;
                break;
            }
        }
        if(!flag)
            cout<<"No Solution"<<endl;
    }
    return 0;
}

紫书习题2-5分数化小数(动态保留小数点后c位)

题目:输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=1e6,c<=100.输入包含多组数据,结束标记是a=b=c=0。
样例输入:
1 6 4
0 0 0
样例输出:
Case 1: 0.1667

我的代码:

#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
    int a,b,c;
    int kase=0;
    while(cin>>a>>b>>c)
    {
        if(a==0 && b==0 && c==0)break;
        cout<<"Case "<<++kase<<": ";
        printf("%.*lf\n",c,a/(double)b);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值