2024年7月上海月赛丙组

求和问题

题目:给n个数,输出最长的前缀长度,使得前缀的和大于等于 0。

分析:前缀和,找到最大的位置

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n;
long long s[N], f[N];
long long ans;
int main(){
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> s[i];
		s[i] += s[i-1];
	}
	for (int i = n; i >= 0; i--) {
		if (s[i] >= 0) {
			cout << i << endl;
			return 0;
		}
	}
	return 0;
}

得分排名

题目:给出n个学生的分数,从大到小排序后输出id

分析:结构体排序

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n;
int s[N];
pair<int, int> p[N];
int main(){
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> s[i];
		p[i] = {-s[i], i};
	}
	sort(p + 1, p + n + 1);
	for (int i = 1; i <= n; i++) {
		cout << p[i].second << endl;
	}
	return 0;
}

录制节目(一)

题目:n 个节目,第 i 个节目从时刻 \(s_{i}\) 开始,到 \(t_{i}\) 结束,没有回放。前一个节目结束时间点和后一个节目开始时间点重合是被允许的。有一台录像机,每台录像机在工作的时候只能录一个节目,最多可以录下多少完整的节目。
分析:经典贪心问题,排序右端点。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, l, r;
int s[N];
pair<int, int> p[N];
bool cmp(pair<int, int> a, pair<int, int> b) {
	return a.second < b.second;
}
int main(){
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> l >> r;
		p[i] = {l, r};
	}
	sort(p + 1, p + n + 1, cmp);
	int cnt = 0, end = 0;
	for (int i = 1; i <= n; i++) {
		if (p[i].first >= end) {
			cnt++;
			end = p[i].second;
		}
	}
	cout << cnt << endl;
	return 0;
}

子集归零

题目:给出 n 个数统计能从 1 到 n 中,选出多少种不同的下标子集,使得这些下标对应的数字之和等于 0。

分析:n范围不到22,考虑状压。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 22 + 10;
int n, cnt;
int s[N];
int main(){
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> s[i];
	}
	for (int i = 0; i < 1 << n; i++) {
		int ans = 0;
		for (int j = 0; j < n; j++)
			if ((i >> j) & 1) {
				ans += s[j];
			}
		if (!ans) cnt++;
	}
	cout << cnt << endl;
	return 0;
}

池塘计数

题目:\(n*m\)的地图里.是水,#是陆地,四联通的水算一个整体,问有多少不联通的池塘。

分析:dfs裸题

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 200 + 10;
int n, m, cnt;
string str[N];
int dx[] = {-1, 0, 0, 1};
int dy[] = {0, -1, 1, 0};
void dfs(int x, int y) {
	str[x][y] = '#';
	for (int i = 0; i < 4; i++) {
		int xx = x + dx[i];
		int yy = y + dy[i];
		if (xx >= 0 && xx < n 
			&& yy >= 0 && yy < m 
				&& str[xx][yy] == '.')
					dfs(xx, yy);
	}
}
int main(){
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> str[i];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (str[i][j] == '.') {
				dfs(i, j);
				cnt++;
			}
		}
	}
	cout << cnt << endl;
	return 0;
}
posted @ 2024-08-16 10:39  forleaves  阅读(52)  评论(0)    收藏  举报