马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
L1-112 当代战争
题目
既然是从大到小轰炸,将全部点存储为三元组(value, x, y)。
排序之后, 记载行列被轰炸的编号,进行 k 次挑选即可。
- #include <bits/stdc++.h>
- using namespace std;
- constexpr int MAXN = 1000;
- struct Node { int val, r, c; };
- static Node v[MAXN*MAXN + 5];
- static int mat[MAXN+5][MAXN+5];
- static bool row_boom[MAXN+5], col_boom[MAXN+5];
- int main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, m, k;
- cin >> n >> m >> k;
- // 1) 读入矩阵,扁平化到 v[]
- int tot = 0;
- for(int i = 1; i <= n; i++){
- for(int j = 1; j <= m; j++){
- cin >> mat[i][j];
- v[tot++] = { mat[i][j], i, j };
- }
- }
- // 2) 按值从大到小排序
- sort(v, v + tot, [](auto &A, auto &B){
- return A.val > B.val;
- });
- // 3) 选 k 个“炸弹”行列
- int cnt = 0;
- for(int i = 0; i < tot && cnt < k; i++){
- int rr = v[i].r, cc = v[i].c;
- if(!row_boom[rr] && !col_boom[cc]){
- row_boom[rr] = true;
- col_boom[cc] = true;
- cnt++;
- }
- }
- // 4) 输出剩余元素
- for(int i = 1; i <= n; i++){
- if(row_boom[i]) continue;
- bool first = true;
- for(int j = 1; j <= m; j++){
- if(col_boom[j]) continue;
- if(!first) cout << ' ';
- cout << mat[i][j];
- first = false;
- }
- if(!first) cout << '\n';
- }
- return 0;
- }
复制代码 L2-051 满树的遍历
题目
先将输入的全括号算式分析成一棵二叉树,然后做后序遍历——即先处理左子树、再处理右子树、末了输出当前节点的利用。输出时,假如左右子节点是叶子数字,就打印该数字;否则不打印。这样完全符合题目要“只输出数字+利用符”的格式要求。
- #include <bits/stdc++.h>
- using namespace std;
- struct Node {
- // 如果 isLeaf,则 val 存数字字符串;否则存操作符 op,以及左右子节点指针
- bool isLeaf;
- string val;
- char op;
- Node *l, *r;
- Node(string v): isLeaf(true), val(move(v)), op(), l(nullptr), r(nullptr) {}
- Node(char c, Node* L, Node* R): isLeaf(false), val(), op(c), l(L), r(R) {}
- };
- string s;
- int pos;
- // 解析函数:根据语法 expr = '(' expr op expr ')' | number
- Node* parse() {
- if (s[pos] == '(') {
- ++pos; // skip '('
- Node* L = parse();
- char oper = s[pos++];
- Node* R = parse();
- ++pos; // skip ')'
- return new Node(oper, L, R);
- } else {
- // 读数字
- int start = pos;
- while (pos < (int)s.size() && isdigit(s[pos])) ++pos;
- return new Node(s.substr(start, pos - start));
- }
- }
- // 后序遍历,按题目要求输出每一步
- void dfs(Node* cur) {
- if (cur->isLeaf) return;
- dfs(cur->l);
- dfs(cur->r);
- // 下面输出:如果左是叶子,先打印数字;然后打印操作符;如果右是叶子,再打印数字
- if (cur->l->isLeaf) cout << cur->l->val;
- cout << cur->op;
- if (cur->r->isLeaf) cout << cur->r->val;
- cout << "\n";
- }
- int main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- // 读入整行
- if (!getline(cin, s)) return 0;
- pos = 0;
- Node* root = parse();
- dfs(root);
- return 0;
- }
复制代码 L2-054 三点共线
题目
可以使用 bitset 优化枚举过这道题。
功能bitsetunordered_set<int>插入/查询速率O(1) (硬件位利用)O(1) 均派(有哈希冲突)空间占用1 bit/值(非常省)至少 8 字节/值 + 哈希桶是否能负数索引❌ 必要 偏移量映射✅ 不限定值域
- #include <bitset>
- bitset<10> b; // 创建一个包含10位的bitset,默认全是0
- b[3] = 1; // 将第4位设为1(下标从0开始)
- b.set(5); // 将第6位设为1
- b.reset(3); // 将第4位设为0
- b.flip(); // 所有位取反
- bool x = b.test(5); // 判断第6位是否为1(返回true/false)
- int cnt = b.count(); // 返回有多少位是1
复制代码
- #include <bits/stdc++.h>
- using namespace std;
- const int D = 1e6; // 坐标偏移量
- bitset<2000010> pos; // 存储y=2的点
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
-
- vector<vector<int>> layers(2); // layers[0]:y=0, layers[1]:y=1
- int n, xpmclzjkln = 0; // 题目要求的中间变量
-
- cin >> n;
- for (int i = 0; i < n; ++i) {
- int x, y;
- cin >> x >> y;
- if (y == 2) {
- pos.set(x + D); // 坐标偏移防止负数
- } else {
- layers[y].push_back(x);
- }
- }
- // 去重排序
- for (auto& layer : layers) {
- sort(layer.begin(), layer.end());
- layer.erase(unique(layer.begin(), layer.end()), layer.end());
- }
- vector<pair<int, int>> ans;
- for (int x0 : layers[0]) {
- for (int x1 : layers[1]) {
- int x2 = 2 * x1 - x0;
- if(x2 < -1E6 || x2 > 1E6) continue;
- if (pos.test(x2 + D)) {
- ans.emplace_back(x0, x1);
- }
- }
- }
- // 按要求排序
- sort(ans.begin(), ans.end(), [](auto& a, auto& b) {
- return tie(a.second, a.first) < tie(b.second, b.first);
- });
- // 输出结果
- if (ans.empty()) {
- cout << -1;
- } else {
- for (auto& [x0, x1] : ans) {
- printf("[%d, 0] [%d, 1] [%d, 2]\n",
- x0, x1, 2*x1 - x0);
- }
- }
- return 0;
- }
复制代码 L2-055 胖达的山头
差分取 max
- #include <bits/stdc++.h>
- using namespace std;
- using ll = long long;
- int parse_time(const string &s) {
- // "hh:mm:ss" -> 秒数
- int hh = stoi(s.substr(0,2));
- int mm = stoi(s.substr(3,2));
- int ss = stoi(s.substr(6,2));
- return hh*3600 + mm*60 + ss;
- }
- int main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- int n;
- cin >> n;
- vector<pair<int,int>> events;
- events.reserve(2*n);
- string s_start, s_end;
- for(int i = 0; i < n; i++){
- cin >> s_start >> s_end;
- int st = parse_time(s_start);
- int ed = parse_time(s_end);
- // [st, ed] 包含端点,故在 ed+1 时做 −1
- events.emplace_back(st, +1);
- events.emplace_back(ed+1, -1);
- }
- // 按时间排序
- sort(events.begin(), events.end(),
- [](auto &a, auto &b){
- if(a.first != b.first)
- return a.first < b.first;
- return a.second < b.second; // +1 也可以先后都累加
- });
- int cur = 0, ans = 0;
- for(auto &e : events){
- cur += e.second;
- ans = max(ans, cur);
- }
- cout << ans << "\n";
- return 0;
- }
复制代码 L2-056 被n整除的n位数
题目
- 用 dfs(pos, prefix) 表现我们已经确定了前 pos-1 位,当前前缀值为 prefix(十进制整数)。
- 若 pos > n,阐明前 n 位都已满足条件,检查这个 prefix 是否在区间 [a, b] 内,假如则生存。
- 对于第 pos 位(1-based,下同),我们尝试的数字 d 必须使得:
( p r e f i x × 10 + d ) m o d p o s = 0. (prefix \times 10 + d) \bmod pos = 0. (prefix×10+d)modpos=0.
- 别的,第 1 位 pos=1 只能枚举 1..9(最高位不能为 0);后续可枚举 0..9,但按照提示:若 pos=n,即剩下末了一位,还要满足「能被 n 整除」,同样由上式天然保证。
- n <= 14 时,深度 DFS 的分支被整除条件严酷限定,一般仅产生几十到几百个候选,远小于暴力 1 0 n 10^n 10n。
- 用 long long 存前缀、比力区间,安全无溢出。
- #include <bits/stdc++.h>
- using namespace std;
- using ll = long long;
- int n;
- ll A, B;
- vector<ll> answer;
- // DFS 生成
- void dfs(int pos, ll prefix) {
- if (pos > n) {
- // 构造了 n 位数,检查区间
- if (prefix >= A && prefix <= B) {
- answer.push_back(prefix);
- }
- return;
- }
- int start = (pos == 1 ? 1 : 0);
- for (int d = start; d <= 9; d++) {
- ll nxt = prefix * 10 + d;
- // 前 pos 位能被 pos 整除
- if (nxt % pos == 0) {
- dfs(pos + 1, nxt);
- }
- }
- }
- int main(){
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- cin >> n >> A >> B;
- answer.clear();
- // n 位数的最小与最大
- ll low = 1;
- for (int i = 1; i < n; i++) low *= 10;
- ll high = low * 10 - 1;
- // 如果 [A,B] 与 n 位数区间无交集,直接无解
- if (B < low || A > high) {
- cout << "No Solution\n";
- return 0;
- }
- // 交集后再 DFS,会节省一点无谓判断
- A = max(A, low);
- B = min(B, high);
- dfs(1, 0LL);
- if (answer.empty()) {
- cout << "No Solution\n";
- } else {
- sort(answer.begin(), answer.end());
- for (ll x : answer) {
- cout << x << "\n";
- }
- }
- return 0;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |