第一题:非降序数组
写一个函数,传入两个非降序的整数数组(A, B),将 A, B 合并成一个非降序数组 C,返回 C(不要使用内置 sort 函数)。
类似于归并排序
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> ans;
int n, m;
cin >> n >> m;
int arr1[n], arr2[m];
for (int i = 0; i < n; ++i) {
cin >> arr1[i];
}
for (int i = 0; i < m; ++i) {
cin >> arr2[i];
}
int i = 0, j = 0;
while (i < n && j < m) {
if (arr1[i] <= arr2[j]) {
cout << arr1[i++] << " ";
} else {
cout << arr2[j++] << " ";
}
}
while (i < n) {
cout << arr1[i++] << " ";
}
while (j < m) {
cout << arr2[j++] << " ";
}
return 0;
}
第二题 吃!吃!吃!
已知n个整数。 每3个数算一个周期。 不足一个周期补0. 在周期的第一个位置的数的权值和等于a1+a[1+3]+… … 第二个位置的数的权值和等于a2+a[2+3]+… … 求三个数的最大权值。 如果最大权值为第一个数,输出’J’; 最大权值为第二个数,输出’H’; 最大权值为第三个数,输出’B’。
输入的时候直接顺便计算三个位置数的权值,然后判断哪个最大
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
int a = 0, b = 0, c = 0;
int x;
for (int i = 1; i <= n; ++i) {
cin >> x;
if (i % 3 == 1) {
a += x;
} else if (i % 3 == 2) {
b += x;
} else {
c += x;
}
}
if (a > b && a > c) {
cout << "J" << endl;
} else if (b > a && b > c) {
cout << "H" << endl;
} else {
cout << "B" << endl;
}
return 0;
}
第三题:计算逆波兰表达式的结果
逆波兰记法中,操作符置于操作数的后面。例如表达“三加四”时,写作“3 4 +”,而不是“3 + 4”。如果有多个操作符,操作符置于第二个操作数的后面,所以常规中缀记法的“3 - 4 + 5”在逆波兰记法中写作“3 4 - 5 +”:先3减去4,再加上5。使用逆波兰记法的一个好处是不需要使用括号。例如中缀记法中“3 - 4 * 5”与“(3 - 4)*5”不相同,但后缀记法中前者写做“3 4 5 * -”,无歧义地表示“3 (4 5 *) -”;后者写做“3 4 - 5 *”。
题目应该有点问题,对于减法【3 4 -】应该表示的是【3-4】,但是答案是按【4-3】计算才能过。
过程就是首先读入字符串,按空格分割,然后用栈去做
if __name__ == "__main__":
arr = input().strip()
lt = arr.split()
op_func={
"+":lambda x,y:int(x+y),
"-":lambda x,y:int(x-y),
"*":lambda x,y:int(x*y),
"/":lambda x,y:int(x/y),
}
stack = list()
for tok in lt:
try:
num = int(tok)
except ValueError:
num2 = stack.pop()
num1 = stack.pop()
num = op_func[tok](num2, num1)
finally:
stack.append(num)
print(stack[0])
第四题:会议安排
开会了!作为一个集体,开会的时候桌子当然是需要和老大相邻的!(老大可能坐在桌子上边) 小艺被分配到排桌椅的活,可是小艺的力气都用在吃上了,怎么可能搬动这些桌椅呢。 她决定用现有的布局当作是会议座位安排。 每个桌子分配一个人。互相连接相同字符表示一个桌子,如UVV表示2张桌子,UVU则表示3张桌子。 小艺想知道选择某个桌子之后老大身边能围多少人?
做的可能有点复杂,先是将属于一个桌子的字符用同一种数字标号(同一个连通块用一种数字),然后再将指定字符对应的数字四周不同的连通块标号存进一个set中,最后统计最大的set集合。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <unordered_set>
#include <map>
using namespace std;
char mp[100 + 5][100 + 5];
int rec[100 + 5][100 + 5];
void dfs(int n, int m, int x, int y, char c, int idx) {
if (x >= n || x < 0 || y >= m || y < 0 || mp[x][y] != c || rec[x][y] != 0) {
return;
}
rec[x][y] = idx;
dfs(n, m, x-1, y, c, idx);
dfs(n, m, x+1, y, c, idx);
dfs(n, m, x, y-1, c, idx);
dfs(n, m, x, y+1, c, idx);
}
int judge(int n, int m, int x, int y, int mark) {
if (x >= n || x < 0 || y >= m || y < 0 || rec[x][y] == 0 || rec[x][y] == mark) {
return 0;
}
return 1;
}
int main() {
int n, m;
char c;
cin >> n >> m >> c;
memset(rec, 0, sizeof rec);
for (int i = 0; i < n; ++i) {
scanf("%s", mp[i]);
}
int idx = 1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (mp[i][j] != '.' && rec[i][j] == 0) {
dfs(n, m, i, j, mp[i][j], idx++);
}
}
}
map<int, unordered_set<int> > res;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (mp[i][j] == c) {
if (judge(n, m, i-1, j, rec[i][j])) res[rec[i][j]].insert(rec[i-1][j]);
if (judge(n, m, i+1, j, rec[i][j])) res[rec[i][j]].insert(rec[i+1][j]);
if (judge(n, m, i, j-1, rec[i][j])) res[rec[i][j]].insert(rec[i][j-1]);
if (judge(n, m, i, j+1, rec[i][j])) res[rec[i][j]].insert(rec[i][j+1]);
}
}
}
int ans = 0;
for (auto item : res) {
ans = max(ans, (int)item.second.size());
}
cout << ans << endl;
return 0;
}