CSDN 第二十次编程竞赛题解

第一题:非降序数组

写一个函数,传入两个非降序的整数数组(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;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值