【题解】CF2013A

  首先抽自己一巴掌,A题自信提交直接WA,故写此题解警示一下(顺便水一水)。

翻译

  原题链接
在这里插入图片描述

思路

  显然,若搅拌机单位时间能处理的水果数 x x x小于人每次丢进去的数量 y y y那人只需要一直扔进去就好了,而搅拌机要考虑的可就多了 。所以直接每次处理 x x x个就行了,不用管 y y y。反之,若 x > y x > y x>y,则每次处理 y y y个就行了。

  整理一下,需要的时间为: t = ⌈ n m i n ( x , y ) ⌉ t=\left \lceil \frac{n}{min(x, y)} \right \rceil t=min(x,y)n,此处为向上取整。

  那我是怎么错的呢——为了方便,我没有用 c e i l ceil ceil方法,而是把式子变成了:

t = ( n − 1 ) / m i n ( x , y ) + 1 t=(n-1) / min(x, y) + 1 t=(n1)/min(x,y)+1

  解释一下,这里利用了C++的整数类型作除法自动向下取整的特点,检查一下 n n n整除或不整除 m i n ( x , y ) min(x,y) min(x,y)两种情况,,就会发现和原式等价。

  但是,关键的地方来了,再读题发现 n n n可以等于 0 0 0,然后这个式子就出问题了……

  解决方法就是加个特判。

代码

#include<bits/stdc++.h>
#define int long long 
using namespace std;
signed main() {
	int t; cin>>t;
	while(t--) {
		int n, x, y; cin>>n>>x>>y;
		if(n == 0) cout<<0<<endl;
		else cout<<(n-1) / min(x, y) + 1<<endl;
	}
}
CF2004A Closet Point是一个常见的数据结构题,通常涉及最小化操作次数的问题。题目描述的是在一个二维网格上找到最短距离的点对,每次可以沿着水平、垂直或对角线移动一格。这个题目常常可以用哈希表(Disjoint Set Union,简称DSU)或者最近点对搜索(Floyd-Warshall Algorithm)来解决。 C++题解概述: ```cpp #include <iostream> #include <vector> #include <set> using namespace std; const int inf = (int)1e9 + 7; vector<int> x[2005], y[2005]; set<pair<int, int>> dist; void init(int n) { for (int i = 1; i <= n; i++) { x[i].clear(); y[i].clear(); dist.insert({i, i}); } } bool sameSet(int u, int v) { return dist.find({u, v}) != dist.end(); } void merge(int u, int v) { if (!sameSet(u, v)) { dist.erase({min(u, v), max(u, v)}); dist.insert({u, v}); } } void dfs(int node, int start, vector<vector<int>>& dp) { dp[node][start] = min(dp[node][start], abs(x[node][start] - x[start][start]) + abs(y[node][start] - y[start][start])); for (auto &p : {x[node], y[node]}) { for (int i = 0; i < p.size(); ++i) { if (i == start || !sameSet(p[i], start)) continue; dfs(node, i, dp); merge(p[i], start); } } } int main() { int n; cin >> n; init(n); for (int i = 1; i <= n; i++) { for (int j = 0; j < 2; j++) { cin >> x[i][j]; for (int k = 1; k < n; k++) { y[k + i][j] = x[i][j]; } } } int m; cin >> m; vector<vector<int>> dp(n + 1, vector<int>(n + 1, inf)); while (m--) { int a, b; cin >> a >> b; if (!sameSet(a, b)) { merge(a, b); } dfs(a, b, dp); } cout << *dist.begin() << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值