04_N阶楼梯上楼问题、输入一个ip地址串,判断是否合法、输入一个四行五列的矩阵,找出每列最大的两个数

来源:互联网 发布:淘宝商品分类数据库 编辑:程序博客网 时间:2024/05/18 13:11
1. 题目描述:
N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)
输入:
输入包括一个整数N,(1<=N<90)。
输出:
可能有多组测试数据,对于每组数据,
输出当楼梯阶数是N时的上楼方式个数。
样例输入:
4
样例输出:
5


  分析:假设 f(n) 为上 n 阶楼梯的方法数量。则如果只有 1 阶楼梯,显然只有一种方法走完;如果有 2 阶楼梯,显然有两种走法走完,所以有 f(0)=0, f(1)=1, f(2)=2。当有 n 阶楼梯时,显然每一步只有两种走法(走一阶或走两阶),第一步的走法也不例外。如果第一步走一阶,那还剩下 n-1 阶,则剩下的楼梯共有 f(n-1) 种走法;如果第一步走两阶,则剩下的楼梯共有 f(n-2) 种走法。从而有:对于 n 阶楼梯,共有 f(n-1) + f(n-2)种走法。从而可以得到推导公式:

                f(0)=0, f(1)=1, f(2)=2, ..., f(n)=f(n-1) + f(n-2)

很明显,这就是我们非常熟悉的 fibonacci 数列,相信无论是其递归程序还是递推程序,大家都很熟悉吧。

参考答案

#include<stdio.h>     void initialize(long int value[], int size)//初始化f(n)的值,避免重复计算{    int k;    value[0] = 0;    value[1] = 1;    value[2] = 2;    for(k=3; k<size; k++)    {        value[k] = value[k-1] + value[k-2];    }} int main()  {      int n;    long int value[91];    initialize(value, 91);     while(scanf("%d", &n) != EOF){          printf("%ld\n", value[n]);//直接利用已计算过的f(n)的值    }      return 0;  }


2. 题目描述:
    输入一个ip地址串,判断是否合法。
输入:
    输入的第一行包括一个整数n(1<=n<=500),代表下面会出现的IP地址的个数。
    接下来的n行每行有一个IP地址,IP地址的形式为a.b.c.d,其中a、b、c、d都是整数。
输出:
    可能有多组测试数据,对于每组数据,如果IP地址合法则输出"Yes!”,否则输出"No!”。
样例输入:
2
255.255.255.255
512.12.2.3
样例输出:
Yes!
No!
提示:
合法的IP地址为:
a、b、c、d都是0-255的整数。

参考答案

#include<stdio.h>int main(){    int n,a,b,c,d;    while(scanf("%d",&n)!=EOF)    {        while(n--)        {            scanf("%d.%d.%d.%d",&a,&b,&c,&d);            if(a>=0 && a<=255 && b>=0 && b<=255 && c>=0 && c<=255 && d>=0 && d<=255)    {                printf("Yes!\n");    }            else    {                printf("No!\n");    }        }    }    return 0;}


  这种解答会被服务器端判断为正确,但是其实此程序有很多bug(如输入不慎会造成死循环等),所以千万是不能用在实际开发当中的。下面让我们再看一下另一个非常严谨的判断程序,此程序在我机器上运行没有问题,但是此程序提交服务器后被判断为错误答案。

#include<stdio.h>    #include<string.h>int main()  {  char str[501][20];int str_len, i, dotnum, flag, sum, n, cur;int temp;while(scanf("%d", &n) != EOF){for(i=0; i<n; i++){scanf("%s", str[i]);}for(cur=0; cur<n; cur++){str_len = strlen(str[cur]);flag = 1;//如果输入的IP长度小于7或大于15,则肯定是错误的if(str_len<7 || str_len>15){flag=0;}for(i=0, dotnum=0; i<str_len && flag; i++){sum =0;while(str[cur][i] != '.' && str[cur][i] != '\0'){//如果当前字符不是 0 到 9 中的整数,则肯定不是合法IPtemp = str[cur][i] - '0';if(temp<0 || temp>9){flag = 0;break;}sum =sum*10 + (str[cur][i++] - '0');}if(sum>255){flag = 0;break;}dotnum++;}if(flag && 4==dotnum){printf("Yes\n");}else{printf("No\n");}}}return 0;  }


3. 题目描述:
    输入一个四行五列的矩阵,找出每列最大的两个数。
输入:
    输入第一行包括一个整数n(1<=n<=1000),接下来的四行每行包括五个整数。代表一个四行五列的矩阵,矩阵元素全部是整数。
输出:
    可能有多组测试数据,对于每组数据,按照样例输出的格式将每列最大的两个数输出,如果最大的两个数中的一个数在这一列中有多个相同的值,则行值取行值小的那一个。
    输出时要保留原矩阵的行列顺序,即在原矩阵中行值小的,在输出矩阵中的行值依然小。
样例输入:
1
1  2   4  9  8
-1  4  9  8  8
12  9  8  7  0
7   8  9  7  0
样例输出:
12 9 9 9 8 
7 8 9 8 8 
提示:
每个数字后面都要输出一个空格

参考答案
#include<stdio.h>    #include<string.h>#include <limits.h>int main()  {  int n, i, k, in_1, in_2;int num[4][5], result[2][5];int max_1 = INT_MIN, max_2 = INT_MIN;while(scanf("%d", &n) != EOF){while(n--){//接收输入数据for(i=0; i<4; i++){for(k=0; k<5; k++){scanf("%d", &num[i][k]);}}//将结果写入result数组中for(k=0; k<5; k++){in_1 = -1;in_2 = -1;max_1 = INT_MIN;max_2 = INT_MIN;/////////////////////////////////////////////////找出最大数for(i=0; i<4; i++){if(num[i][k] > max_1){in_1 = i;max_1 = num[i][k];}}//找出次大数for(i=0; i<4; i++){//in_1 != i是为了跳过已求得的最大数if(num[i][k] > max_2 && in_1 != i){in_2 = i;max_2 = num[i][k];}}//////////////////////////////////////////////////////////////////保留原矩阵的行顺序if(in_1 > in_2){in_1 = in_1 + in_2;in_2 = in_1 - in_2;in_1 = in_1 - in_2;}result[0][k] = num[in_1][k];result[1][k] = num[in_2][k];}//输出结果for(i=0; i<2; i++){for(k=0; k<5; k++){printf("%d ", result[i][k]);}printf("\n");}}}return 0;  }


原创粉丝点击