信息学奥赛一本通(C++版) 第一部分 C++语言 第六章 函数

时间:2024-04-14 18:59:16

信息学奥赛一本通(C++版) 第一部分 C++语言 第六章 函数

第一节 函数

//1150 求正整数2和n之间的完全数
#include <stdio.h>
int f(int n){
    int i,sum=0;
    for(i=1;i<n;i++)
        if(n%i==0)sum+=i;
    return sum;
}
int main(){
    int n,i;
    scanf("%d",&n);
    for(i=2;i<=n;i++)
        if(i==f(i))
            printf("%d\n",i);
    return 0;
}


//1151 素数个数
#include <stdio.h>
int isPrime(int a){//判断质数
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int main(){
    int n,i,cnt=0;
    scanf("%d",&n);
    for(i=2;i<=n;i++)
        if(isPrime(i))cnt++;
    printf("%d",cnt);
    return 0;
}

//1152 最大数max(x,y,z)
//提交,未通过,猜测,存在分母为0的情况,仔细读题
//再读代码,发现 竟然是 笔误,一道简单的题,漏了函数。
//补上漏掉的函数,提交AC
#include <stdio.h>
int max(int a,int b){
    return a>b?a:b;
}
int main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    printf("%.3lf",max(max(a,b),c)*1.0/max(max(a+b,b),c)/max(max(a,b),b+c));// 此处写成,造成未通过printf("%.3lf",(max(a,b),c)*1.0/max(max(a+b,b),c)/max(max(a,b),b+c));
    return 0;
}

//1153 绝对素数
#include <stdio.h>
int isPrime(int n){
    int i;
    if(n<2)return 0;
    if(n==2)return 1;
    for(i=2;i*i<=n;i++)
        if(n%i==0)return 0;
    return 1;
}
int f(int n){
    int a;
    a=n%10*10;
    a+=n/10;
    return a;
}
int main(){
    int i;
    for(i=11;i<=97;i++)
        if(isPrime(i)&&isPrime(f(i)))
            printf("%d\n",i);
    return 0;
}


//1154 亲和数
#include <stdio.h>
int f(int n){
    int i,sum=0;
    for(i=1;i<n;i++)
        if(n%i==0)sum+=i;
    return sum;
}
int main(){
    int a,b;
    for(a=2;a<=999999;a++){
        b=f(a);
        if(a==f(b)&&a!=b){
            printf("%d %d",a,b);
            break;
        }
    }
    return 0;
}

//1155 回文三位数
#include <stdio.h>
int isPrime(int n){
    int i;
    if(n<2)return 0;
    if(n==2)return 1;
    for(i=2;i*i<=n;i++)
        if(n%i==0)return 0;
    return 1;
}
int isData(int n){
    int a,b;
    a=n/100,b=n%10;
    if(a==b)return 1;
    else return 0;
}
int main(){
    int i;
    for(i=100;i<=999;i++)
        if(isPrime(i)&&isData(i))
            printf("%d\n",i);
    return 0;
}
//1156 求π的值
//该题题目有误,正确公式如下:
//根据公式arctanx(x)=x-x^3 /3+x^ 5 /5-x ^7 /7+…和 π=6 arctanx(1/sqrt(3)),定义函数arctanx(x),求当最后一项小于 10^-6 时 π的值。
//知道 π的值 为3.1415926也是该题纠错的一个技巧。
//提交,未通过,将输出的%lf改成%g,提交,未通过。
//printf("%.10lf\n",6.0*f(1/sqrt(3)));//翻了原书 明白自己编写 AC 是不可能完成任务,本人写法 printf("%lf\n",6.0*f(1/sqrt(3)));
//修改,提交AC 2017-10-27 6:54

//1156 求π的值
//再次翻阅《信息学奥赛一本通(C++版)》,将书中代码敲了一遍,提交AC,据此对原来代码进行修改
//题中有一句很关键,求当最后一项小于10-6时π的值
//公布该题的测试数据:
//3.1415905109
//几点说明:原书代码 需要勘误:t=x;//此处写成 t=0.0
//http://ybt.ssoier.cn:8088常作测试数据更新的操作,即过一段时间,AC的程序变成未通过的程序
//本人遇到两例 1156 求π的值    1372 小明的账单
//以下代码为最新AC 代码 2018-1-2 21:21
#include <stdio.h>
#include <math.h>
double f(double x){
    double sum=0,a=x;
    int k=0;
    while(fabs(a/(2*k+1))>=1e-6){
        sum+=a/(2*k+1);
        k++;
        a*=x*x*(-1);
    }
    return sum;
}
int main(){
    printf("%.10lf\n",6.0*f(1/sqrt(3)));//翻了原书 明白自己编写 AC 是不可能完成任务,本人写法 printf("%lf\n",6.0*f(1/sqrt(3)));
    return 0;
}

//1157 哥德巴赫猜想
#include <stdio.h>
int isPrime(int n){
    int i;
    if(n<2)return 0;
    if(n==2)return 1;
    for(i=2;i*i<=n;i++)
        if(n%i==0)return 0;
    return 1;
}
int main(){
    int i,j,a,b;
    for(i=6;i<=100;i++)
        if(i%2==0){
            for(j=2;j<i;j++){
                a=j,b=i-j;
                if(isPrime(a)&&isPrime(b)){
                    printf("%d=%d+%d\n",i,a,b);
                    break;
                }
            }
        }
    return 0;
}

//1397 简单算术表达式求值
//读题发现 (运算符前后可能有空格)  
#include <stdio.h>
#include <string.h>
char a[100];
int b[5];
int main(){
    int len,i,k=0;//此处原是 int len,i,k;
    char cmd,c;
    while((c=getchar())!='\n')//此句无法读取空格scanf("%s",a);
        a[k++]=c;
    a[k]='\0';
    len=strlen(a);
    i=0,k=0;
    while(i<len){
        if('0'<=a[i]&&a[i]<='9'){
            b[k]=(a[i]-'0')*10+a[i+1]-'0';
            i+=2;
            k++;
        }else if(a[i]!=' '){
            cmd=a[i];
            i++;
        }else
            i++;
    }
    if(cmd=='+')printf("%d",b[0]+b[1]);
    else if(cmd=='-')printf("%d",b[0]-b[1]);
    else if(cmd=='*')printf("%d",b[0]*b[1]);
    else if(cmd=='/')printf("%d",b[0]/b[1]);
    else if(cmd='%')printf("%d",b[0]%b[1]);
}


//1398 短信计费
#include <stdio.h>
int f(int b){
    int cnt=1;
    while(b>70){
        b-=70;
        cnt++;
    }
    return cnt;
}
int main(){
    int n,i,a;
    double sum=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&a);
        sum+=f(a)*0.1;
    }
    printf("%.1lf",sum);
    return 0;
}

//1399 甲流病人初筛
#include <stdio.h>
#include <string.h>
struct node{
    char name[100];
    double t;
    int tag;
}p;
int main(){
    int n,i,cnt=0,tag;
    char name[100];
    double t;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%s%lf%d",name,&t,&tag);
        if(t>=37.5&&tag==1){
            printf("%s\n",name);
            cnt++;
        }
    }
    printf("%d",cnt);
    return 0;

}

//1400 统计单词数

2.统计单词数

https://www.luogu.org/problemnew/show/P1308可提交测评

// P1308 统计单词数
//对该题,题意不明,感觉抓狂,出题,还是要经得起推敲
//因要读入空格,故采用getchar();
//样例通过,提交80分,测试点9,10 WA
//反复读题,发现 1≤ 文章长度≤1,000,000。 即有可能 文章中最长的字符串 长度为 1000000
//修改,提交AC,
//反馈,该题出得太烂,语意不明,不清之处 至少有两处。
//测试数据中,文章中单词的长度,尽然可以超过20
//一句话,让应试者不在读题上失分,是出题者应注意的。
//提交AC 2018-5-4
//看了此次代码,发现,写得比2017-3-13 还要棒
#include <stdio.h>
#include <string.h>
char a[20],b[1000100];//此处写成 b[20] 又是查数据,又是看代码 ,最后还是读题才解决的
void toLower(char a[]){//字符串转小写
    int len,i;
    len=strlen(a);
    for(i=0;i<len;i++)
        if('A'<=a[i]&&a[i]<='Z')
            a[i]=a[i]-'A'+'a';
}
int cmp(char a[],char b[]){//相同 返回1 否则返回 0
    int len_a,len_b,i;
    len_a=strlen(a);
    len_b=strlen(b);
    if(len_a!=len_b)
        return 0;
    for(i=0;i<len_a;i++){
        if('A'<=b[i]&&b[i]<='Z')
            b[i]=b[i]-'A'+'a';
        if(a[i]!=b[i])
            return 0;
    }
    return 1;
}
int main(){
    char c;
    int cnt=0,len=0,pos=-1,num=0;
    scanf("%s",a);
    toLower(a);
    while((c=getchar())!='\n');//吸收 换行 //此处写成while((c=getchar())!='\r');不行
    while(c=getchar()){//此处写成 (c=getchar())!=EOF
        cnt++;
        if(c==' '||c==EOF){
            b[len]='\0';
            if(len>0)//开始比较
                if(cmp(a,b)){
                    num++;
                    if(num==1)
                        pos=cnt-len-1;
                }
            len=0;
            if(c==EOF)break;
        }else
            b[len++]=c;
    }
    if(pos==-1)printf("-1");
    else printf("%d %d",num,pos);
    return 0;
}


//1400 统计单词数
//题目的难度在于从字符串中解析出单词 
//提交,未通过,
//一翻,发现洛谷也有这道题,P1308 统计单词数
//网址如下:https://www.luogu.org/problem/show?pid=1308
//NOIP 2011 普及组第2题
//数据范围
//1≤ 单词长度≤10。
//1≤ 文章长度≤1,000,000。
//noip2011普及组第2题
//修改数据范围,还是未通过, 
//翻出以往编写的代码http://blog.****.net/mrcrack/article/details/61419446
//提交AC 
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char s1[20];
char s2[1000000+10];
int main(){
    int count=0;
    char c;
    int i,j;
    int s1len,s2len;
    int flag;
    int num,k;
    scanf("%s",s1);
    
    //字符串s2读取,比较费力 
    while((c=getchar())!=EOF)
        if(c!='\r'&&c!='\n')
            s2[count++]=c;
    while(!isalpha(s2[count-1]))
        count--;
    s2[count]='\0';
    
    s1len=strlen(s1);
    s2len=strlen(s2);
    
    //s1,s2字符串,转化成小写 
    for(i=0;i<s1len;i++)
        if(isalpha(s1[i])&&s1[i]>='A'&&s1[i]<='Z')
            s1[i]='a'+s1[i]-'A';
    for(i=0;i<s2len;i++)
        if(isalpha(s2[i])&&s2[i]>='A'&&s2[i]<='Z')
            s2[i]='a'+s2[i]-'A';
    
    num=0;
    for(i=0;i<s2len;i++){
        flag=0;
        for(j=0;j<s1len;j++){
            if(s2[i+j]==s1[j])
                flag=1;
            else{
                flag=0;
                break;
            }
        }
        if(flag==1){
            if(s2[i+s1len]==' '||i+s1len==count){//i+s1len==count表示结尾
                if(i==0||s2[i-1]==' '){//开头
                    num++;
                    if(num==1)
                        k=i;
                } 
            } 
        }
    }
    if(num>0)
        printf("%d %d\n",num,k);
    else
        printf("-1\n");
    return 0;

//1401 机器翻译
//发现思路更清晰,队列应用更得心应手
//样例通过,提交AC 2018-5-10
#include <stdio.h>
#define maxn 1100
int M,N,q[maxn];
int main(){
    int h,t,v,i,cnt=0;//cnt外存中查找次数
    scanf("%d%d",&M,&N);
    h=t=1;
    while(N--){
        scanf("%d",&v);
        for(i=h;i<t;i++)
            if(q[i]==v)//内存中找到
                break;
        if(i==t){//内存中找不到
            cnt++;
            if(t-h<M){//内存中有空间
                q[t]=v,t++;
            }else{//内存中无空间
                h++,q[t]=v,t++;
            }
        }
    }
    printf("%d",cnt);
    return 0;
}


1401 机器翻译

//http://blog.****.net/mrcrack/article/details/61625530

4.p1540 机器翻译

NOIP2010 提高组 复赛 translate 机器翻译

1.读题,很快弄明题意,单词不在内存中就查字典,统计查字典次数。

2.内存采用队列方式。统计进队列次数,即为查询次数。

3.程序很快编好,两个样例通过,提交20分,重新读题,发现误解题意,清空的不是第一个内存块内容,而是第一个单词内容,修改,两个样例通过,提交20分,发现,反复读题,发现内存容量用的是样例1中的3,马上修改成m,提交AC.

4.心里素质还好,此题读下来,肯定能拿100分的,所以要反复尝试,绝不能跳过,做下一道。

5.有一点要注意,队列要开1000+10。

耗时:35分钟(从拿到题目开始,其中经历两次20分,第三次AC)

附上AC代码,编译环境Dev-C++4.9.9.2

//2010 translate
#include <stdio.h>
int queue[1000+10];//队列
int main(){
    int head,tail,cur;
    int m,n,v,count;
    int i;
    scanf("%d%d",&m,&n);
    head=0;
    tail=0;
    count=0;
    for(i=0;i<n;i++){
        scanf("%d",&v);
        cur=head;//遍历队列
        while(cur!=tail){
            if(queue[cur]==v)
                break;
            cur++;
        }
        if(cur==tail){//队列中没找到
            //队列容量未到m
            if(tail-head<m){
                queue[tail]=v;
                tail++;
            }else{//队列容量已是m
                queue[tail]=v;
                tail++;
                head++;
            }
            count++;
        }else{//队列中找到
             //无需查字典,故不进行操作
        }
    }
    printf("%d\n",count);
    return 0;
}

//1402 Vigenère密码

http://blog.****.net/mrcrack/article/details/52303717

NOIP2012 提高组 复赛 day1 vigenere vigenere密码

1、经过《算法竞赛入门经典(第2版)》第三章 数组和字符串 的训练,此题几乎没费什么力,代码就写出了。

2、写代码过程中的一个失误是将输入读成密码,明文,输出为密文,改起来没费什么周折,只是将+改成-。

3、编译后,输出与预想的不一样,跟踪调试上花了点时间,很快就改好了。

4、输出结束后要不要回撤换行,斗争了小一会,最后决定加上,不然怎么判断是完整的一行呢。

5、经对拍对比,此题10个输入输出完全正确,100分。

 

编译环境Dev-C++4.9.9.2

附上代码:

 #include <stdio.h>
#include <string.h>


char k[100+10],m[1000+10];
int main(){
    int klen,mlen;
    int i,j;
    int pos;
    char c;
    scanf("%s%s",k,m);
    klen=strlen(k);
    mlen=strlen(m);
    for(i=0;i<mlen;i++){
        j=i%klen;
        if(k[j]>='A'&&k[j]<='Z'){//大写字母
            pos=k[j]-'A';//确定偏移位置
        }else{//小写字母
            pos=k[j]-'a';
        }
        if(m[i]>='A'&&m[i]<='Z'){//大写字母
            c='A'+(m[i]-'A'-pos+26)%26;
            printf("%c",c);
        }else{//小写字母
            c='a'+(m[i]-'a'-pos+26)%26;
            printf("%c",c);
        }
       
    }
    putchar('\n');//换行
    return 0;
}

洛谷 P1079 Vigenère 密码
//1403 素数对
#include <stdio.h>
int isPrime(int a){
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int main(){
    int n,i=2;
    scanf("%d",&n);
    while(i<=n){
        if(i+2<=n&&isPrime(i)&&isPrime(i+2))printf("%d %d\n",i,i+2);
        i++;
    }
    return 0;
}
//1404 我家的门牌号
//n a b
//(1+b)*b/2-a*3=n
//a=((1+b)*b-2*n)/6
#include <stdio.h>
int main(){
    int n,a,b;
    scanf("%d",&n);
    for(b=1;b<=n;b++){
        a=((1+b)*b-2*n)/6;
        if(0<a&&a<=b&&(1+b)*b-6*a==2*n){
            printf("%d %d",a,b);
            break;
        }
    }
    return 0;
}
//1405 质数的和与积
//和一定,两数相等时,积最大
#include <stdio.h>
#include <math.h>
int isPrime(int a){
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int main(){
    int n,i;
    scanf("%d",&n);
    for(i=n/2+1;i>=2;i--){
        if(isPrime(i)&&isPrime(n-i)){
            printf("%d",i*(n-i));
            break;
        }
    }
    return 0;
}

//1406 单词替换
//题目设计使该题比较简单。 
#include <stdio.h>
#include <string.h>
char s[210][100]; 
int main(){
    int k=0,i;
    while(scanf("%s",s[k])!=EOF)k++;
   for(i=0;i<k-2;i++)
        if(strcmp(s[i],s[k-2])==0)
            strcpy(s[i],s[k-1]);
    for(i=0;i<k-2;i++){//低级错误,此处写成 for(i=0;i<k-2;k++)查了好久 
        if(i)printf(" ");
        printf("%s",s[i]);
    }
    return 0;
}

//1407 笨小猴
http://blog.****.net/mrcrack/article/details/61625530

6.洛谷 p1125 笨小猴

NOIP2008 提高组 复赛 word 笨小猴

1.看完题目,是字符串操作。

2.做一个字母到整数的映射,a-0,b-1,c-2,......

3.开一个26个元素的整型数组,统计字母个数,完毕后,一次遍历,找出最大值,最小值。

4.最多次数-最小次数,对结果判定是否质数。

5.判定素数时,分三种情况讨论,0,1;2;3,4,5.....

6.代码在经历i<26时,写成了i<len,调试了3分钟。

7.样例通过后,提交AC

耗时:30分钟

难度:简单

附上AC代码,编译环境Dev-C++4.9.9.2

//2008 word 笨小猴
#include <stdio.h>
#include <string.h>
char s[100+10];
int a[26];
int main(){
    int len;
    int i,j;
    int min,max;
    int t;
    memset(a,0,sizeof(a));
    scanf("%s",s);
    len=strlen(s);
    for(i=0;i<len;i++){
        a[s[i]-'a']++;
    }
    min=999;
    max=-1;
    for(i=0;i<26;i++){//找出最小值,最大值 ,此处len,应改成26 ,查了会
        if(a[i]>0){
            if(min>a[i])
                min=a[i];
            if(max<a[i])
                max=a[i];
        }
    }
    if(min!=999&&max!=-1){//判段是否质数
        t=max-min;
        if(t<2){
            printf("No Answer\n");
            printf("0\n");
        }else if(t==2){
            printf("Lucky Word\n");
            printf("2\n");
        }else{//t>2
            for(i=2;i<t;i++)
                if(t%i==0){//非质数
                    break;
                }
            if(i==t){//质数
                printf("Lucky Word\n");
                printf("%d\n",t);
            }else{//非质数
                printf("No Answer\n");
                printf("0\n");
            }
        }
    }else{
        printf("No Answer\n");
        printf("0\n");
    }
    return 0;
}


//1408 素数回文数的个数
//题目输入有误:一个大于11小于1000的整数n。
//应改成:一个大于等于11小于1000的整数n。
#include <stdio.h>
int isPrime(int a){
    int i;
    if(a<0)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int isData(int a){
    if(1<=a&&a<=99){
        if(a/10==a%10)return 1;
        else return 0;
    }else if(100<=a&&a<=999){
        if(a/100==a%10)return 1;
        else return 0;
    }
}
int main(){
    int n,i,cnt=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        if(isPrime(i)&&isData(i))cnt++;
    printf("%d",cnt);
    return 0;
}


//1409 判决素数个数
#include <stdio.h>
int isPrime(int a){
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int main(){
    int i,x,y,cnt=0;
    scanf("%d%d",&x,&y);
    for(i=x;i<=y;i++)
        if(isPrime(i))cnt++;
    printf("%d",cnt);
    return 0;
}

//1410 最大质因子序列
//什么是质因子,解释如下:在数论里,某一正整数的质因子指能整除该数的质数整数。
//比较担忧判重,一看样例,顾虑消除
#include <stdio.h>
int isPrime(int a){
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int main(){
    int m,n,i,j,k=0;
    scanf("%d%d",&m,&n);
    for(i=m;i<=n;i++)
        for(j=i;j>1;j--)
            if(i%j==0&&isPrime(j)){
                if(k)printf(",");
                printf("%d",j);
                k++;
                break;
            }
    return 0;
}

//1411 区间内的真素数
//提交,未通过,读题,发现 漏了 该句 如果之间没有真素数,则输出No。
//修改,提交AC
#include <stdio.h>
int isPrime(int a){
    int i;
    if(a<2)return 0;
    if(a==2)return 1;
    for(i=2;i*i<=a;i++)
        if(a%i==0)return 0;
    return 1;
}
int f(int a){
    int b=0;
    while(a){
        b*=10;
        b+=a%10;
        a/=10;
    }
    return b;
}
int main(){
    int m,n,i,k=0;
    scanf("%d%d",&m,&n);
    for(i=m;i<=n;i++)
        if(isPrime(i)&&isPrime(f(i))){
            if(k)printf(",");
            printf("%d",i);
            k++;
        }
    if(k==0)printf("No");
    return 0;
}



//1412 二进制分类
#include <stdio.h>
int cnt_a=0,cnt_b=0;
int f(int n){//cnt_1>cnt_0 A 否则B
    int cnt_1=0,cnt_0=0;
    while(n){
        if(n%2==0)cnt_0++;
        else cnt_1++;
        n/=2;
    }
    return cnt_1>cnt_0;
}
int main(){
    int i;
    for(i=1;i<=1000;i++)
        if(f(i))cnt_a++;
        else cnt_b++;
    printf("%d %d",cnt_a,cnt_b);
    return 0;
}

//1413 确定进制
//该题有缺漏,原题来自https://vjudge.net/problem/POJ-1331
//里面提到2<=B<=16
//该题算法,统统将B进制化成10进制,比较是否相等。
//仔细再看题目,发现看走眼了,题目中有说明B(2<=B<=40) 
//http://blog.****.net/u012349696/article/details/36429827技巧不错,摘抄如下:
//B不一定要从2开始遍历 由r=n%k我们可以知道 r一定是要小于k的 所我们只需要找到表达式三个数所含数字中最大的那个值,B则从那个值+1开始遍历 
#include <stdio.h>
int max(int a,int b){
    return a>b?a:b;
}
int f(int a,int b){//b进制 
    int ans=0,d[10],k=0,i,f=1;
    while(a)k++,d[k]=a%10,a/=10;
    for(i=1;i<=k;i++)ans+=d[i]*f,f*=b;
    return ans;
}
int main(){
    int p,q,r,B;
    int b;
    scanf("%d%d%d",&p,&q,&r);
    b=max(max(p%10,q%10),r%10)+1;
    for(B=b;B<=40;B++){
        if(f(p,B)*f(q,B)==f(r,B)){
            printf("%d",B);
            return 0;
        }
    }
    printf("0");
    return 0;
}

2017-10-27 22:47 AC 该节内容

第二节 递归算法

//1158 求1+2+3.+...
#include <stdio.h>
int f(int n){
    if(n==1)return 1;
    return n+f(n-1);
}
int main(){
    int n;
    scanf("%d",&n);
    printf("%d",f(n));
    return 0;
}

//1159 斐波那契数列
//挺奇怪的,为什么通过,只得40分,int改成long long 还是40分
#include <stdio.h>
int f(int n){
    if(n==1)return 0;
    if(n==2)return 1;
    return f(n-1)+f(n-2);
}
int main(){
    int n;
    scanf("%d",&n);

    printf("%d",f(n));

    return 0;

}

//1159 斐波那契数列 2018-5-14
#include <stdio.h>
int f(int n){
    if(n==1)return 0;
    if(n==2)return 1;
    return f(n-2)+f(n-1);
}
int main(){
    int n;
    scanf("%d",&n);
    printf("%d",f(n));
    return 0;
}

上述 1159 斐波那契数列 程序执行过程如下2018-5-14:

信息学奥赛一本通(C++版) 第一部分 C++语言 第六章 函数

//1160 倒序数
//样例通过,提交AC 2018-5-9 21:05
#include <stdio.h>
void num(int n){
    if(n==0)
        return;
    printf("%d",n%10);
    num(n/10);
}
int main(){
    int n;
    scanf("%d",&n);
    num(n);
    return 0;
}

//1160 倒序数
#include <stdio.h>
void print(int a){
    if(a/10==0){
        printf("%d",a%10);
        return ;
    }
    printf("%d",a%10);
    print(a/10);
}
int main(){
    int a;
    scanf("%d",&a);

    print(a);

    return 0;

}

//1161 转进制
//编着编着,越来越能体会到递归与栈的联系,可喜可贺。
#include <stdio.h>
int x,m;
void print(int a){
    if(a>=10)printf("%c",'A'+a-10);
    else printf("%d",a);
}
void f(int a){
    if(a==0)return;
    f(a/m);
    print(a%m);
}
int main(){
    scanf("%d%d",&x,&m);

    f(x);

    return 0;

}

//1161 转进制
//样例通过,提交AC 2018-5-10
//看了代码,发现,还是之前代码写得好
#include <stdio.h>
int n,m;
void print(int n){
    switch(n){
        case 10:
            printf("A");
            break;
        case 11:
            printf("B");
            break;
        case 12:
            printf("C");
            break;
        case 13:
            printf("D");
            break;
        case 14:
            printf("E");
            break;
        case 15:
            printf("F");
            break;
        default:
            printf("%d",n);
    }
}
void change(int n){
    if(n==0)
        return ;
    change(n/m);
    print(n%m);
}
int main(){
    scanf("%d %d",&n,&m);
    change(n);//漏了此句,一直没有输出,查了会,真是想不到会漏。
    return 0;
}

//1162 字符串逆序
//样例通过,提交AC 2018-5-10
//看了看之前的代码,发现是两种味道,读者,自取所需
#include <stdio.h>
#include <string.h>
#define maxn 1000
char in[maxn];
void output(char s[],int pos){
    if(pos==-1){
        return ;
    }
    printf("%c",s[pos]);
    output(s,pos-1);
}
int main(){
    int len;
    scanf("%s",in);
    len=strlen(in);
    output(in,len-2);
    return 0;
}


//1162 字符串逆序
#include <stdio.h>
#include <string.h>
int len;
char s[10000];
void print(int step){
    if(step==len-1)return ;
    print(step+1);
    printf("%c",s[step]);
}
int main(){
    scanf("%s",s);
    len=strlen(s);
    print(0);
    return 0;
}


//1163 阿克曼(Ackmann)函数
//抽空,改成阅读程序写结果,手动试试
#include <stdio.h>
int akm(int m,int n){
    if(m==0)return n+1;
    if(n==0)return akm(m-1,1);
    return akm(m-1,akm(m,n-1));
}
int main(){
    int m,n;
    scanf("%d%d",&m,&n);
    printf("%d",akm(m,n));
    return 0;
}

//1164 digit函数
//提交,未通过,仔细排查,发现少了return ;
//修改,提交AC
#include <stdio.h>
void digit(int n,int k){
    if(k==1){
        printf("%d",n%10);
        return;//漏了该句导致未通过。
    }
    digit(n/10,--k);
}
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    digit(n,k);
    return 0;
}

//1165 Hermite多项式
//可以考虑将此题改成阅读程序写结果
#include <stdio.h>
double h(int n,int x){
    if(n==0)return 1.0;
    if(n==1)return 2.0*x;
    return 2.0*x*h(n-1,x)-2.0*(n-1)*h(n-2,x);
}
int main(){
    int n,x;
    scanf("%d%d",&n,&x);
    printf("%.2lf",h(n,x));
    return 0;
}

//1166 求f(x,n)
#include <stdio.h>
#include <math.h>
double f(double x,int n){
    if(n==1)return sqrt(1+x);
    return sqrt(n+f(x,n-1));
}
int main(){
    int n;
    double x;
    scanf("%lf%d",&x,&n);
    printf("%.2lf",f(x,n));
}

//1167 再求f(x,n)
//递归多少有点感觉了
#include <stdio.h>
double f(double x,int n){
    if(n==1)return x/(1+x);
    return x/(n+f(x,n-1));
}
int main(){
    int n;
    double x;
    scanf("%lf%d",&x,&n);
    printf("%.2lf",f(x,n));
    return 0;
}

2017-10-27 AC该节内容

2017-10-27 22:47 AC该章节内容


2017-10-27 22:47 AC 第一部分 C++语言 内容


2018-1-2 21:21 AC该章节内容