牛客周赛 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';
}
相关推荐
诚丞成6 分钟前
滑动窗口篇——如行云流水般的高效解法与智能之道(1)
算法
手握风云-15 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
怀澈1221 小时前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
chnming19871 小时前
STL关联式容器之set
开发语言·c++
带多刺的玫瑰2 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔2 小时前
《线性代数的本质》
线性代数·算法·决策树
威桑2 小时前
MinGW 与 MSVC 的区别与联系及相关特性分析
c++·mingw·msvc
熬夜学编程的小王2 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins2 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
Mr.132 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++