这是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,欢迎指正~~