北京航空航天大学 2012年复试上机题 解题报告

题目来自这里: http://www.cskaoyan.com/viewthread.php?tid=87299
因为没在OJ上AC 所以不保证程序一定正确
===============================
第一题:分解整数
某些整数能分解成若干个连续整数的和的形式,例如
15 = 1 + 2+3+4+5 
15 = 4 + 5 + 6
15 = 7 + 8
某些整数不能分解为连续整数的和,例如:16
输入:一个整数N(N <= 10000)
输出:整数N对应的所有分解组合,按照每个分解中的最小整数从小到大输出,每个分解占一行,每个数字之间有一个空格(每行最后保留一个空格);如果没有任何分解组合,则输出NONE。
样例输入:
15
16
样例输出:
1 2 3 4 5 
4 5 6 
7 8 
NONE 

本题还可以先用筛选法求出5000以内的素数 再对输入的数字N做素因数分解 从其素因数中 找出全部的奇数因子(可以是和数) 为分解序列的个数 而剩下的因子的乘积即为分解序列的中间元素 如果两者的结合合法 即可输出该序列 如35=5x7 那么7作为中间元素 有5+6+7+8+9的序列 但5做序列中间元素时不合法
如果输入的是N是偶数 则要考虑其分解序列的元素个数为偶数的情况 做N/2的处理 就转化为求N/2的分解序列 此时如果能分解成奇数个连续数相加 则说明分解成功 补全接续下去的另外一半分解序列 即为对N的偶数个元素的分解序列了 如果N/2还是偶数 就还可以算N/4是否有奇数个元素的分解序列 直到不再是偶数 算其最后一个奇数个元素的分解序列
不过这个方法过于复杂 并不适合本题的考试环境 出题人也不是想这么考大家的 想考的就是底下这个很简单的算法:
#include <stdio.h>
main()
{
	int i, j, k, l, m, n, temp;
	bool fail;
	while( scanf("%d",&n) == 1 ){
		fail = 1;
		m = 2 * n;
		l = n / 2;
		//cout << m << " " << l << endl;
		for( i=1; i<=l; i++ ){
			for( j=i+1; j<n; j++ ){
				temp = (i+j)*(j-i+1);
				//cout << temp << endl;
				if( temp > m )  break;
				if( temp == m ){
					fail = 0;
					for( k=i; k<=j; k++ )
						printf("%d ",k);
					puts("");
				}
			}
		}
		if(fail) puts("NONE");
	}
}


第二题:小岛面积
1 1 1 1 1 1
1 1 0 0 0 1
1 0 0 0 1 0
1 1 0 1 1 1
0 1 0 1 0 0
1 1 1 1 1 1
上面矩阵的中的1代表海岸线,0代表小岛。求小岛面积(即被1中包围的0的个数)。注意:仅求这样的0,该0所在行中被两个1包围,该0所在列中被两个1包围。
输入:第一行输入一个整数N,表示输入方阵的维数 输入一个N维方阵
输出:小岛面积
样例输入:
6
1 1 1 1 1 1
1 1 0 0 0 1
1 0 0 0 1 0
1 1 0 1 1 1
0 1 0 1 0 0
1 1 1 1 1 1
样例输出:
8

对给出的方阵四周加一圈1 表示海岸线 就可以统一处理所有的元素 而无需对每个元素都判断其是否在边界并做不同处理了
#include<stdio.h>
int a[100][100];

main()
{
	int i, j, k, l, m, n;
	freopen("2012_2_island.txt","r",stdin);//
	
	while( scanf("%d",&n)==1 ){
		l = n+2;
		for( i=0; i<l; i++ )
			for( j=0; j<l; j++ ){
				if(i==0 || j==0 || i==n+1 || j==n+1) a[i][j] = 1;
				else scanf("%d",&a[i][j]);
			}
			
		for( i=1, m=0; i<=n; i++ )
			for( j=1; j<=n; j++ ){
				if( a[i][j] == 0 ){
					if( a[i+1][j]==1 && a[i-1][j]==1 || a[i][j+1]==1 && a[i][j-1]==1 )
						m++;
				}
			}

		printf("%d\n",m);
	}
}


第三题:统计关键字
输入一行标准c语言代码(字符个数小于300),统计出该字符串中关键字的if,while,for所在的位置,按照关键字出现的顺序依次输出。注意双引号内的不需要统计。
输入:一行标准c语言代码,字符个数小于300
输出:关键字if,while,for对应的位置,按照关键字出现的顺序依次输出。输出格式为:关键字,后跟冒号,然后是出现的位置。扫描到关键字就输出,每个输出占一行。
样例输入:
#include <stdio.h> int main() {int i = 0; if(i == 0) printf("YES"); return 0;}
#include <stdio.h> int main() {int ifwhile = 0; int forif = 1;char if_for_while = 'a';char *str = "while"; while(ifwhile == 0) {ifwhile = 1;forif = 0;} if(forif == 0) {if_for_while = 'b';} if(ifwhile == 1) {if_for_while = 'c';} return 0;}
样例输出:
if:43
while:88
if:133
if:170

这道题 我怀疑回忆题目的人把答案搞错了 样例2的输出似乎应该是while:108  if:153  if:190
#include <string.h>
#include <stdio.h>
char s[302];

main()
{
	int i, j, k, l, m, n, w;
	freopen("2012_3_string.txt","r",stdin);//
	bool valid;
	i = 0, w = 0;
	while( gets(s) ){
		l = strlen(s);
		//cout << l << endl;
		valid = 1;
		for(i=0;i<l;i++){
			if( s[i] == '"' ) valid = 1 - valid;	//遇到双引号
			if( !valid ) continue;
			if( s[i] == 'i' ){
				if( s[i+1] == 'f'
					&& ( s[i+2] == ' ' || s[i+2] == '(' )
					&& ( s[i-1] == ' ' || s[i-1] == ';' ) )
						printf("if:%d\n",i+1);
				}
			else if( s[i] == 'w' ){
				if( s[i+1] == 'h' && s[i+2] == 'i' && s[i+3] == 'l' && s[i+4] == 'e'
					&& ( s[i+5] == ' ' || s[i+5] == '(' )
					&& ( s[i-1] == ' ' || s[i-1] == ';' ) )
						printf("while:%d\n",i+1);
			}
			else if( s[i] == 'f' ){
				if( s[i+1] == 'o' && s[i+2] == 'e'
					&& ( s[i+3] == ' ' || s[i+3] == '(' )
					&& ( s[i-1] == ' ' || s[i-1] == ';' ) )
						printf("for:%d\n",i+1);
			}
		}
	}
}

你可能感兴趣的:(北京航空航天大学 2012年复试上机题 解题报告)