2006年中科大计算机考研复试机试题

这是2006年USTC的机试试题,试题来源于网络,解答为我的原创。转载请注明出处。谢谢~

01.读int矩阵文件,将之转置后输出

// 简单,无需解释
#include <stdio.h>

int main()
{
	int m, n;    //A[m][n]
	int A[100][100];
	int i, j;

	while (scanf ("%d %d", &m, &n) != EOF)
	{
		for (i = 0; i < m; i++)            //读入矩阵
			for (j = 0; j < n; j++)
				scanf ("%d", &A[i][j]);

		for (i = 0; i < n; i++)           //输出逆转的矩阵
		{
			for (j = 0; j < m; j++)
				printf ("%d ", A[j][i]);
			printf ("\n");
		}
	}
	return 0;
}

02.给出时间格式 [年,月], 判断此月有多少天.

// 核心是判断闰年的方法
#include <stdio.h>

bool isYun (int year)
{
	if (year%4==0 && year%100!=0 || year%400==0)     //不是世纪年且能被4整除或者是世纪年能被400整除
		return 1;
	return 0;
}


int main()
{
	int y, m;
	int mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	
	while (scanf ("[%d,%d]", &y, &m) != EOF)
	{
		if (isYun(y))    //是闰年
			mon[1] = 29;
		else
			mon[1] = 28;

		printf ("%d\n", mon[m-1]);
		getchar();
	}
	return 0;
}

03.给出一些标识符,判断合法标识符有多少个

// C语言的合法标识符:以字母或下划线开头,由字母、数字或者下划线构成的字符串
#include <stdio.h>
#include <ctype.h>
#include <string.h>

bool isValid (char s[])
{
	int len = strlen(s);
	int i;
	if (isalpha(s[0]) || s[0] == '_')   //字母或下划线开头
	{
		for (i = 1; i < len; ++i)
		{
			if (isdigit(s[i]) || isalpha(s[i]) || s[i] == '_')
				continue;
			else
				return 0;
		}
		return 1;
	}
	return 0;
}

int main()
{
	char id[100];
	int tot = 0;
	while (gets(id))
	{
		if (isValid(id))
		{
			printf("%s\n", id);
			tot++;
		}
		else
			continue;
	}
	printf ("There are %d valid ID\n", tot);
	return 0;
}


04.给出无向图连接矩阵,求各个连同分量.

如:Input:

ABCDEFGH
0 1 0 0 0 0 1 1
1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0
0 0 0 1 0 1 0 0
0 0 0 1 1 0 0 0
1 0 0 0 0 0 0 1
0 1 0 0 0 0 1 0

Output:

The 1 th connection is:ABHG
The 2 th connection is:C
The 3 th connection is:DEF

//当对某一顶点进行深搜时,可以遍历到这个顶点所在连通图的所有节点
#include <stdio.h>
#include <string.h>

#define MAXV 50

int graph[MAXV][MAXV];     //图的矩阵表示
bool vis[MAXV];            //是否已访问的标志
char s[MAXV];              //顶点的字母表示
int nVertices;             //顶点的个数

void dfs(int v)       //深度优先遍历
{
	vis[v] = 1;	//修改为已访问		
	printf ("%c ", s[v]);
	int i;
	for (i = 0; i < nVertices; ++i)
		if (!vis[i] && graph[v][i])    //没有访问且有边
			dfs(i);
}

int main()
{
	int i, j;
	while (gets(s))
	{
		memset(vis, 0, sizeof(vis));         //访问标志初始化
		memset(graph, 0, sizeof(graph));     //图矩阵初始化

		nVertices = strlen(s);
		for (i = 0; i < nVertices; ++i)      //读入图的矩阵
			for (j = 0; j < nVertices; ++j)
				scanf ("%d", &graph[i][j]);

		int index = 1;
		for (i = 0; i < nVertices; ++i)    //对所有的节点,看是否已经访问
		{
			if (!vis[i])
			{
				printf ("The %dth connection is:", index++);
				dfs(i);
				printf ("\n");
			}
			
		}
	}
	return 0;
}

5.给出一个整数分解成连续整数的和.

//sum[i] 记录了前i个数的和,从i~j的和用sum[j]-sum[i-1] 计算,若与n相等则输出
#include <stdio.h>

int main()
{
	int n;
	int i, j, k;
	int sum[1000];       //sum[i] --- 前i个数的和
	sum[0] = 0;
	for (i = 1; i < 1000; ++i)
		sum[i] = sum[i-1] + i;

	while (scanf ("%d", &n) != EOF)
	{
		for (i = 1; i <= n/2; ++i)    //i为起始位置,j为终止位置,计算i~j的和
		{
			int ok = 0;
			for (j = i; j <= n/2; ++j)
			{
				if (sum[j] - sum[i-1] == n)    //相等
				{
					ok = 1;
					break;
				}
				else if (sum[j] - sum[i-1] > n)   //大于,无需将j后移,因为越加会越大
					break;
			}
			if (ok)
			{
				for (k = i; k <= j; k++)    //输出
					printf ("%d ", k);
				printf ("\n");
			}
		}
	}
	return 0;
}

6.给出带括号的四则运算表达式,要求给出逆波兰式

#include <cstdio>
#include <cctype>
#include <stack>
using namespace std;

bool compare (char op1, char op2)    //比较优先级,op1为当前操作符,op2为栈顶操作符
{
        // 若op1优先级比op2高,返回1;否则返回0.
	if (op1 == '+' || op1 == '-')
		if (op2 == '#' || op2 == '(')
			return 1;
		else
			return 0;
	else if (op1 == '(')
		return 1;
	else
		if (op2 == '*' || op2 == '/')
			return 0;
		else 
			return 1;
}

int main()
{
	int val;
	char ch, op;
	char exp[100];
	stack<char> opStack;
	opStack.push('#');
	int i, len;

	while (gets(exp))
	{
		i = 0;
		len = strlen(exp);
		while (i < len)
		{
			ch = exp[i];
			if (isdigit(ch))   //是数字
			{
				val = ch - '0';
				while (isdigit(exp[++i]))
					val = val * 10 + exp[i] - '0';
				i--;      //退回
				printf ("%d", val);
			}
			else if (ch != ')')    //不为')‘
			{
				op = opStack.top();
				if (compare(ch, op))     //ch > op,压入
					opStack.push(ch);
				else
				{
					while (!compare(ch, op))    //ch < op,弹出直到op比ch优先级高
					{
						printf ("%c", op);
						opStack.pop();
						op = opStack.top();
					}
					opStack.push(ch);
				}
			}
			else if (ch == ')')     //右括号,弹出栈中操作符直道遇到’(‘,并且将'('弹出
			{
				op = opStack.top();
				while (op != '(')
				{
					printf ("%c", op);
					opStack.pop();
					op = opStack.top();
				}
				opStack.pop();
			}
			i++;
		}
		
		op = opStack.top();
		while (op != '#')
		{
			printf ("%c", op);
			opStack.pop();
			op = opStack.top();
		}
		printf("\n");
	}
	return 0;
}

7.递归列出的所有选择方法.

例如m=3,n=4时(4选3),结果为

1,2,3

1,2,4

1,3,4

2,3,4

//求出1~n长度为m的子集
#include <stdio.h>

void search(int m, int A[], int n, int cur)  
{
	int i, j;
	if (cur == m)    //长度为m 输出
	{
		printf ("%d", A[0]);
		for (i = 1; i < m; ++i)
			printf (",%d", A[i]);
		printf ("\n");
		return ;
	}

	int s = (cur == 0 ? 1 : A[cur-1] + 1);   //
	for (i = s; i <= n; ++i)   
	{
		A[cur] = i;
		int ok = 1;
		for (j = 0; j < cur; ++j)   
			if (A[j] == i)   //如果已经能够使用到则返回
			{
				ok = 0;
				break;
			}
		if (ok)
			search(m, A, n, cur+1);
	}
}

int main()
{
	int A[10];

	int m, n; 
	while (scanf ("%d %d", &m, &n) != EOF)
	{
		search(n, A, m, 0);
	}
	return 0;
}

代码有可能有BUG,欢迎指正~~


你可能感兴趣的:(c,search,Graph,input,语言,output)