牛客周赛 Round 54

清楚姐姐的糖葫芦

思路:模拟

cpp 复制代码
void solve() {
	string s; cin >> s;
	int ans = 0;
	for (auto i : s) ans += (i == 'o');
	cout << ans << '\n';
}

清楚姐姐买竹鼠

思路:全买 b b b,全买 a a a和混合买的取最小值

cpp 复制代码
void solve() {
	int a, b, x; cin >> a >> b >> x;
	cout << min({x / 3 * b + (x % 3) * a, a * x, (x + 2) / 3 * b}) << '\n';
}

竹鼠饲养物语

思路:直接将饲料种类存到 m a p map map里面,最后遍历 m a p map map模拟整个过程即可

cpp 复制代码
void solve() {
	int n, m; cin >> n >> m;
	map<int, int> mp;
	for (int i = 1, x; i <= n; i ++) {
		cin >> x;
		mp[x] ++;
	}
	int lst = 0, ans = 0, cnt = INF;
	for (auto [x, y] : mp) {
        cout << x << ' ' << y << '\n';
		if (x - lst == 1) {
			lst = x;
			ans += min(cnt, y);
			cnt = min(cnt, y);
		} else break;
	}
	cout << ans << '\n';
}

清楚姐姐跳格子

思路:注意到 n n n的范围只有 1000 1000 1000,大于 1000 1000 1000的因子没有用,所以我们直接暴力枚举因子,然后建边直接跑 b f s bfs bfs即可,因为边权都是 1 1 1

cpp 复制代码
void solve() {
	int n; cin >> n;
	vector<int> a(n + 1);
	for (int i = 1; i <= n; i ++) cin >> a[i];
	vector<vector<int>> g(n + 1);
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			if (a[i] % j == 0) {
				if (i + j <= n) g[i].push_back(i + j);
				if (i - j >= 1) g[i].push_back(i - j);
			}
		}
	}
	queue<int> q;
	q.push(1);
	vector<int> vis(n + 1), dis(n + 1);
	dis[1] = 0;
	vis[1] = 1;
	while (q.size()) {
		auto t = q.front();
		q.pop();
		for (auto v : g[t]) {
			if (vis[v]) continue;
			dis[v] = dis[t] + 1;
			q.push(v);
			vis[v] = 1;
		}
	}
	cout << dis[n] << '\n';
}

清楚姐姐的布告规划

思路:背包 d p dp dp,只是转移的时候要加入条件,只有第 i i i个布告可以覆盖第 i i i个位置的时候我才进行转移

cpp 复制代码
void solve() {
	int n; cin >> n;
	vector<int> len(n + 1);
	int sum = 0;
	for (int i = 1; i <= n; i ++) {
		cin >> len[i];
	}
	vector<int> dp(n + 1, INF);
	dp[0] = 0;
	for (int i = 1; i <= n; i ++) {
		for (int j = n; j >= len[i]; j --) {
			if (dp[j - len[i]] != INF) {
				if (i > j - len[i] && i <= j)
					dp[j] = min(dp[j], dp[j - len[i]] + 1);
			}
		}
	}
	if (dp[n] == INF) cout << -1 << '\n';
	else cout << dp[n] << '\n';
}

竹鼠,宝藏与故事

思路:先选一条可以到达 n n n m m m的路径加入队列,再从这些点往外面 d f s dfs dfs,只要这个点不是最初的 d f s dfs dfs的起点,并且下一个点是和前面的路径联通,我就加入队列,当结束时就找出了全部的路径

cpp 复制代码
int n, m;
int g[1010][1010], lj[1010][1010];
int ans, cnt;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
queue<array<int, 2>> q;
unordered_map<int, unordered_map<int, int>> vis;

void dfs(int x, int y) {
	for (int i = 0; i < 4; i ++) {
		int tx = x + dx[i];
		int ty = y + dy[i];
		if (tx < 1 || ty < 1 || tx > n || ty > m || vis[tx][ty] || g[tx][ty] == -1) continue;
		vis[tx][ty] = 1;
		dfs(tx, ty);
		if (lj[tx][ty]) {
			lj[x][y] = 1;
			q.push({tx, ty});
		}
	}
}


void dfs1(int x, int y) {
	for (int i = 0; i < 4; i ++) {
		int tx = x + dx[i];
		int ty = y + dy[i];
		if (tx < 1 || ty < 1 || tx > n || ty > m) continue;
		if (vis[tx][ty] || g[tx][ty] == -1) continue;
		if (!lj[tx][ty]) {
			vis[tx][ty] = 1;
			dfs1(tx, ty);
		}
		if (lj[tx][ty] && lj[x][y] != 2) {
			lj[x][y] = 1;
			q.push({x, y});
		}
	}
}

void solve() {
	cin >> n >> m;
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= m; j ++) {
			cin >> g[i][j];
		}
	}
	lj[n][m] = 1;
	vis[1][1] = 1;
	dfs(1, 1);
	while (q.size()) {
		auto [x, y] = q.front();
		q.pop();
		lj[x][y] = 2;
		vis.clear();
		vis[x][y] = 1;
		dfs1(x, y);
	}
	int ans = 0;
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= m; j ++) {
			if (lj[i][j]) {
				ans += g[i][j];
			}
		}
	}
	if (!lj[1][1]) ans = 0;
	cout << ans << '\n';
}
相关推荐
霁月风几秒前
设计模式——观察者模式
c++·观察者模式·设计模式
橘色的喵1 分钟前
C++编程:避免因编译优化引发的多线程死锁问题
c++·多线程·memory·死锁·内存屏障·内存栅栏·memory barrier
泉崎5 分钟前
11.7比赛总结
数据结构·算法
你好helloworld7 分钟前
滑动窗口最大值
数据结构·算法·leetcode
何曾参静谧37 分钟前
「C/C++」C/C++ 之 变量作用域详解
c语言·开发语言·c++
AI街潜水的八角1 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple1 小时前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少1 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs111 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋2 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法