// 解法 1:分成四种情况来讨论 voidsolve1(){ cin >> a >> b >> c; if (a + b == c || a + c == b || b + c == a || (a == b && b == c)) cout << "Yes" << endl; else cout << "No" << endl; }
// 解法 2:只要 sum 能被 abc 中的最大值整除即可 voidsolve2(){ cin >> a >> b >> c; int mx = max({a, b, c}); int sum = a + b + c; if (sum % mx == 0) cout << "Yes" << endl; else cout << "No" << endl; }
voidsolve(){ // 读入数据 cin >> h >> w >> x >> y; for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) cin >> g[i][j]; cin >> s; // 1-base 转换为 0-base x--, y--; // 遍历每个指令 for (auto c : s) { int d = trans(c); // 计算下一个点的坐标 int a = x + dx[d], b = y + dy[d]; // 越界 if (a < 0 || a >= h || b < 0 || b >= w) continue; // 撞墙 if (g[a][b] == '#') continue; // 如果是第一次遇见'@',计数+1 if (g[a][b] == '@' && !st[a][b]) { st[a][b] = true; res++; } // 更新坐标 x = a, y = b; }
// 输出结果 cout << x + 1 << " " << y + 1 << " " << res << endl; }
举例:对于数据结构 map<int , set<int>> mx 来说,key 存储的是每个房子的 x 坐标,value 存的是相同 x 坐标的所有 y 坐标的值。那么在一次移动中,一定会对应左右端点。那么使用二分在 set 中查找左右端点,中间的值就是经过的点。将这几个点从 set 中清除掉,就实现了只计算一次经过的功能。
Map mx, my; vector<int> temp; int n, m; // 点的数量,移动次数 LL x, y; // 起始坐标 LL res; char d; // 临时变量,记录移动方向 LL c; // 临时变量,记录移动距离
// voidrun(LL x, LL y, LL u, LL v, Map& i, Map& j){ // 判断点的位置是否合法 if (i[x].empty()) return; if (abs(x) > 1e9 || abs(y) > 1e9) return;
temp.clear();
auto bg = i[x].lower_bound(y + u); auto ed = i[x].upper_bound(y + v);
// 从 bg 到 ed 之间所有的元素都要删除并计数 for (auto it = bg; it != ed; it++) { res++; temp.push_back((*it)); }
// 在原始数组中删除经过的点 for (auto p : temp) { i[x].erase(p); j[p].erase(x); } }
voidsolve(){ // 读入数据 cin >> n >> m >> x >> y; for (int i = 1, u, v; i <= n; i++) { cin >> u >> v; mx[u].insert(v); // x 下有多少个 y my[v].insert(u); // y 下有多少个 x } // 处理所有移动 for (int i = 1; i <= m; i++) { char d; cin >> d >> c; // 读入移动方向和距离
if (d == 'U') run(x, y, 0, c, mx, my), y += c; if (d == 'D') run(x, y, -c, 0, mx, my), y -= c; if (d == 'L') run(y, x, -c, 0, my, mx), x -= c; if (d == 'R') run(y, x, 0, c, my, mx), x += c; }
for (int i = 0; i < n - 1; i++) { cin >> a >> b; a--, b--;
tree[a].push_back(b); tree[b].push_back(a);
deg[a]++; deg[b]++; }
int res = n; // 遍历每个节点 for (int v = 0; v < n; v++) { vector<int> d; // 获取和 v 相连的点的度数 for (auto to : tree[v]) d.push_back(deg[to]); // 按照度数降序排列 sort(d.begin(), d.end(), greater<int>());
for (int i = 1; i <= d.size(); i++) { int num = d[i - 1] * i + 1; res = min(res, n - num); } }