VP Educational Codeforces Round 5


A. Comparing Two Long Integers

题意:给你两个可能包含前导零的数字,判断它们的大小关系。

去除前导零后,先判断位数,位数相同再判断大小。

点击查看代码
void solve() {
    std::string a, b;
    std::cin >> a >> b;
    std::reverse(a.begin(), a.end());
    std::reverse(b.begin(), b.end());
    while (a.size() > 1 && a.back() == '0') {
    	a.pop_back();
    }

    while (b.size() > 1 && b.back() == '0') {
    	b.pop_back();
    }


    std::reverse(a.begin(), a.end());
    std::reverse(b.begin(), b.end());
    if (a.size() == b.size()) {
    	if (a > b) {
    		std::cout << ">\n";
    	} else if (a < b) {
    		std::cout << "<\n";
    	} else {
    		std::cout << "=\n";
    	}
    } else if (a.size() > b.size()) {
    	std::cout << ">\n";
    } else {
    	std::cout << "<\n";
    }
}

B. Dinner with Emma

题意:给你一个矩阵,第一个人选择行,第二个人选择列,结果就是改行列格子上的数。第一个希望结果更大,第二个希望结果更小。求结果。

因为第二个人肯定选一行中最小的那一个,所以第一个人应该选择最小数最大的一行。

点击查看代码
void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector a(n, std::vector<int>(m));
    int max = 0;
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < m; ++ j) {
    		std::cin >> a[i][j];
    	}
    	max = std::max(max, *std::min_element(a[i].begin(), a[i].end()));
    }

    std::cout << max << "\n";
}

C. The Labyrinth

题意:给你一个字符矩阵,有些地方是障碍,有些地方是空地,判断每个障碍变成空地后所在的空地联通块有多少空地。

用并查集维护空地联通块及其个数,然后对于每个障碍将相邻的空地联通块加到set里去重记录答案即可。

点击查看代码
struct DSU {
	std::vector<int> fa, cnt;
	DSU(int _n) {
		init(_n);
	}

	void init(int _n) {
		fa.assign(_n, 0);
		cnt.assign(_n, 1);
		std::iota(fa.begin(), fa.end(), 0);
	}

	int find(int x) {
		return x == fa[x] ? x : fa[x] = find(fa[x]);
	}

	bool merge(int x, int y) {
		x = find(x), y = find(y);
		if (x == y) {
			return false;
		}

		fa[y] = x;
		cnt[x] += cnt[y];
		return true;
	}

	bool same(int x, int y) {
		return find(x) == find(y);
	}

	int size(int x) {
		return cnt[find(x)];
	}
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::string> s(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> s[i];
    }

    auto get = [&](int i, int j) -> int {
    	return i * m + j;
    };

    const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

    DSU dsu(n * m);
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < m; ++ j) {
    		if (s[i][j] == '.') {
    			for (int k = 0; k < 4; ++ k) {
    				int x = i + dx[k], y = j + dy[k];
    				if (x < 0 || x >= n || y < 0 || y >= m || s[x][y] == '*') {
    					continue;
    				}

    				dsu.merge(get(i, j), get(x, y));
    			}
    		}
    	}
    }

   	std::vector<std::string> ans(n, std::string(m, '.'));
   	for (int i = 0; i < n; ++ i) {
   		for (int j = 0; j < m; ++ j) {
   			if (s[i][j] == '*') {
   				std::set<int> set;
   				for (int k = 0; k < 4; ++ k) {
    				int x = i + dx[k], y = j + dy[k];
    				if (x < 0 || x >= n || y < 0 || y >= m || s[x][y] == '*') {
    					continue;
    				}

    				set.insert(dsu.find(get(x, y)));
    			}

    			int sum = 1;
    			for (auto & id : set) {
    				sum += dsu.size(id);
    			}
    			ans[i][j] = '0' + sum % 10;
   			}
   		}
   	}

   	for (int i = 0; i < n; ++ i) {
   		std::cout << ans[i] << "\n";
   	}
}

D. Longest k-Good Segment

题意:给你一个数字,判断最长的子序列其中不同元素不超过k个。

双指针经典题,维护每个数出现次数双指针扫描记答案。

点击查看代码
void solve() {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    const int N = 1e6 + 5;
    std::vector<int> cnt(N);
    int ans = 0, ansl = 0, ansr = 0, sum = 0;
    for (int i = 0, j = 0; j < n;) {
    	while (j < n && sum + (cnt[a[j]] == 0) <= k) {
    		if ( ++ cnt[a[j]] == 1) {
    			++ sum;
    		}
    		++ j;
    	}

    	if (j - i > ans) {
    		ans = j - i;
    		ansl = i;
    		ansr = j - 1;
    	}

		if ( -- cnt[a[i]] == 0) {
			-- sum;
		}
		++ i;
    }

    std::cout << ansl + 1 << " " << ansr + 1 << "\n";
}

E. Sum of Remainders

题意:给你两个数n,m,求i=1mn%i的值。

也是经典题,今年牛客寒假集训营考过。
考虑数论分块,对于每个[l,r],有任意的i[l,r],j[l,r]nl=nr,则n对它们取模的模数形成一个等差序列,首项为n%l,公差为nl

点击查看代码
void solve() {
    i64 n, m;
    std::cin >> n >> m;
    Z ans = (Z)std::max(0ll, m - n) * n;
    m = std::min(m, n);

    for (i64 l = 1; l <= m;) {
    	i64 r = std::min(m, n / (n / l));
    	Z a = n % l, d = n / l;
    	ans += (Z)(r - l + 1) * (a + a - d * (Z)(r - l)) / 2;
    	l = r + 1;
    }

    std::cout << ans << "\n";
}

F. Expensive Strings

待补

posted @   maburb  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示