牛客周赛 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';
}
相关推荐
橘颂TA几秒前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹3 分钟前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
liulilittle5 分钟前
OPENPPP2 网络驱动模式
开发语言·网络·c++·网络协议·信息与通信·通信
mjhcsp9 分钟前
C++ AC 自动机:原理、实现与应用全解析
java·开发语言·c++·ac 自动机
寻星探路14 分钟前
【算法通关】双指针技巧深度解析:从基础到巅峰(Java 最优解)
java·开发语言·人工智能·python·算法·ai·指针
余瑜鱼鱼鱼15 分钟前
Java数据结构:从入门到精通(十)
数据结构
wen__xvn15 分钟前
力扣第 484 场周赛
算法·leetcode·职场和发展
好奇龙猫19 分钟前
【大学院-筆記試験練習:线性代数和数据结构(5)】
数据结构·线性代数
YuTaoShao27 分钟前
【LeetCode 每日一题】865. 具有所有最深节点的最小子树——(解法一)自顶向下
算法·leetcode·职场和发展
爱吃生蚝的于勒28 分钟前
【Linux】进程间通信之匿名管道
linux·运维·服务器·c语言·数据结构·c++·vim