现在的位置: 首页 > 综合 > 正文

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

2013年02月23日 ⁄ 综合 ⁄ 共 3049字 ⁄ 字号 评论关闭

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 中的整数,则肯定不是合法IP
					temp = 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;  
}

抱歉!评论已关闭.