说明
- 华为机试会预先帮你引用所有可能用到的头文件,做题时不用再去引用。
- 华为机试这三题所用到的数组都不会很大,最大也没超过500。
- 由于过去十天了,题目有些地方描述可能不是很到位,若有错误,请指正。
第一题(100分)
题目描述: 有若干房间,房间编号范围为整型变量范围,存在若干单向门,每个单向门连接两个房间,使得只能从一个房间进入另一个房间,请找出只有入口没有出口的房间(只有一个)。 输入描述:第一行为单向门个数,后面每两个数a和b表示从a房间到b房间有单向门。 输出描述:输出没有出口的房间。 示例: 输入:5 1 3 2 5 3 2 5 4 1 4 输出:4
思路:创建一个二维数组存储单向门的起点和终点。用两个for循环,第一个for循环?遍历单向门终点,第二个for循环遍历起点,若某个终点没有找到对应的起点,则输出并跳出循环。
代码:
#include <stdio.h>
int main() {
int a[100][2] = { 0 };
int n;
bool flag;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d%d", &a[i][0], &a[i][1]);
for (int i = 0; i < n; i++) {
flag = true;
for (int j = 0; j < n; j++)
if (a[i][1] == a[j][0]){
flag = false;
break;
}
if (flag) {
printf("%d", a[i][1]);
break;
}
}
return 0;
}
第二题(200分)
题目描述:如图,有一片蜂巢,其中一部分被污染了,以P(polluted)标注,剩下的没被污染,以C(clean)标注。 输入描述:第一行为蜂巢的长宽,之后为每个格子的状态。 输出描述:请输出未被污染的蜂巢的区域个数。 示例: 输入: 2 3 P P C C P C 则蜂巢如图所示: 输出:2
思路:修改原数组 创建pollute函数,作用是把连起来的干净蜂巢污染,即把对应位置的" C"改成" P",这样在遍历的时候不会重复计算。 main函数中设置计数器,每遇到一个干净的蜂巢,计数器加一并调用pollute函数污染该区域。?
代码:
#include <stdio.h>
void pollute(char a[100][100], int m, int n, int i, int j) {
if (a[i][j] == 'P')
return;
a[i][j] = 'P';
for (int k = -1; k <= 1; k++)
for (int l = -1; l <= 1; l++)
if ((i + k >= 0 && i + k < m) && (j + l >= 0 && j + l < n)
&& k * l != 1)
pollute(a, m, n, i + k, j + l);
}
int main() {
char a[100][100] = { 0 };
int m, n, sum = 0;
scanf("%d%d", &m, &n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
scanf(" %c", &a[i][j]);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (a[i][j] == 'C') {
sum++;
pollute(a, m, n, i, j);
}
printf("%d", sum);
return 0;
}
第三题(300分)
题目描述:有一19×19的棋盘,上面分布着若干黑棋和若干白棋,其中白棋用“1”表示,黑棋用“2”表示,没有棋子的地方用“0”表示。现定义如下规则:黑白棋中连成一片的最大数量较大者获胜,否则平局。 输入描述:输入为19×19个数字表示棋盘。 输出描述:第一行为白棋连成一片的最大数,第二行为黑棋连成一片的最大数,第三行若白棋胜,则输出“White”;若黑棋胜,则输出“Black”,若平局,则输出“Draw”。 示例: 输入: 1 1 1 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 输出: 5 4 White
?思路:类似第二题,修改原数组 ?创建turn递归函数,若和参数kind相同,则改变当前位置,统计修改并返回周围相同棋子数。 main函数中,使用max1和max2记录当前最大数量,cur1和cur2用来临时存储turn的返回值并和max1,max2比较。
代码:
#include <stdio.h>
int turn(int a[19][19], int i, int j, int kind) {
if ((i < 0 || i >= 19) || (j < 0 || j >= 19)
|| a[i][j] != kind)
return 0;
a[i][j] = 0;
return 1 + turn(a, i - 1, j, kind) + turn(a, i + 1, j, kind) + turn(a, i, j - 1, kind) + turn(a, i, j + 1, kind);
}
int main() {
int a[19][19] = { 0 };
int cur1, cur2;
int max1 = 0, max2 = 0;
for (int i = 0; i < 19; i++)
for (int j = 0; j < 19; j++)
scanf("%d", &a[i][j]);
for (int i = 0; i < 19; i++)
for (int j = 0; j < 19; j++) {
if (a[i][j] == 1) {
cur1 = turn(a, i, j, 1);
max1 = max1 > cur1 ? max1 : cur1;
}
else if (a[i][j] == 2) {
cur2 = turn(a, i, j, 2);
max2 = max2 > cur2 ? max2 : cur2;
}
}
printf("%d\n%d\n", max1, max2);
if (max1 > max2)
printf("White");
else if (max1 < max2)
printf("Black");
else
printf("Draw");
return 0;
}
|