首页 > 其他分享 >2024 ICPC ShaanXi Provincial Contest

2024 ICPC ShaanXi Provincial Contest

时间:2024-08-14 14:28:09浏览次数:15  
标签:Provincial Contest int vi cin long 2024 vector using

A. chmod

模拟

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {
    string s;
    cin >> s;
    int a = s[0] - '0', b = s[1] - '0', c = s[2] - '0';
    if (a & 4) cout << "r";
    else cout << "-";
    if (a & 2) cout << "w";
    else cout << "-";
    if (a & 1) cout << "x";
    else cout << "-";

    if (b & 4) cout << "r";
    else cout << "-";
    if (b & 2) cout << "w";
    else cout << "-";
    if (b & 1) cout << "x";
    else cout << "-";

    if (c & 4) cout << "r";
    else cout << "-";
    if (c & 2) cout << "w";
    else cout << "-";
    if (c & 1) cout << "x";
    else cout << "-";

    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}

B. Expression Matrix

搜索,首先要尽可能多的使用符号,所以可以dp 出放置符合最多的方案。

然后搜索枚举每一个符号是加还是乘。

考虑一个剪枝优化,只有当符号所在的行或列存在两个11的时候才能使用加,否则只能使用乘

#include <bits/stdc++.h>

using namespace std;

using i32 = int;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int, int>;
const int INF = LLONG_MAX / 2;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector f(n + 1, vi(m + 1));
    int T = 0;
    vector<pii> opt;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            if (i == 1 or j == 1 or i == n or j == m) f[i][j] = 1;
            else if (f[i - 1][j] == 1 and f[i][j - 1] == 1) f[i][j] = -(T++), opt.emplace_back(i, j);
            else f[i][j] = 1;
        }

    vector<vi> r(n + 1);
    for (int i = 1, pre; i <= n; i++) {
        pre = 0;
        for (int j = 1; j <= m; j++) {
            if (f[i][j] == 1) pre = pre * 10 + 1;
            else r[i].push_back(pre), r[i].push_back(f[i][j]), pre = 0;
        }
        r[i].push_back(pre);
    }

    vector<vi> c(m + 1);
    for (int j = 1, pre; j <= m; j++) {
        pre = 0;
        for (int i = 1; i <= n; i++) {
            if (f[i][j] == 1) pre = pre * 10 + 1;
            else c[j].push_back(pre), c[j].push_back(f[i][j]), pre = 0;
        }
        c[j].push_back(pre);
    }

    vi cntR(n + 1);
    for (int i = 1; i <= n; i++)
        for (auto j: r[i])
            if (j == 11) cntR[i]++;

    vi cntC(m + 1);
    for (int j = 1; j <= m; j++)
        for (auto i: c[j])
            if (i == 11) cntC[j]++;

    vi op(T), res;
    int ans = INF;
    auto calc = [&](const vi &v) -> int {
        vi x;
        for (int i: v) {
            if (i > 0) x.push_back(i);
            else if (op[-i] == 0) x.push_back(-1);
        }
        vi y;
        for (int i = 0; i < x.size(); i++) {
            if (x[i] > 0) y.push_back(x[i]);
            else i++, y.back() *= x[i];
        }
        return accumulate(y.begin(), y.end(), 0ll);
    };

    auto dfs = [&](auto dfs, int i) -> void {
        if (i == T) {
            int sum = 0;
            for (int i = 1; i <= n; i++)
                sum += calc(r[i]);
            for (int j = 1; j <= m; j++)
                sum += calc(c[j]);
            if (sum < ans) ans = sum, res = op;
            return;
        }
        auto [ix, iy] = opt[i];
        if (cntR[ix] >= 2 or cntC[iy] >= 2) {
            op[i] = 1;
            dfs(dfs, i + 1);
        }
        op[i] = 0;
        dfs(dfs, i + 1);
    };

    dfs(dfs, 0);

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (f[i][j] == 1) cout << 1;
            else cout << "*+"[res[-f[i][j]]];
        }
        cout << "\n";
    }
    return 0;
}

C. Seats

这到题目,把\(i\)向\(a_i\)连一条有向边,图就是内向基环树森林,其中有两种,一种是链,且最后一个点一定是空节点,此时链上所有点均可满足。另一种是内向基环树,此时只有环上的点可以满足。

所以可以用拓扑序求出链的长度,并且拓扑序没有入队的点就是环上的点。

#include <bits/stdc++.h>

using namespace std;

using i32 = int;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int, int>;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    int N = n * 2;
    vector<vi> e(N + 1);
    vi vis(N + 1), dis(N + 1), deg(N + 1);

    for (int i = 1, x; i <= n; i++)
        cin >> x, e[i].push_back(x), deg[x]++;

    queue<int> q;
    for (int i = 1; i <= N; i++)
        if (deg[i] == 0) q.push(i);

    while (not q.empty()) {
        int x = q.front();
        vis[x] = 1;
        q.pop();
        for (auto y: e[x]) {
            dis[y] = max(dis[x], dis[x] + 1);
            if (--deg[y] == 0) q.push(y);
        }
    }
    int res = 0;
    for (int i = 1; i <= N; i++) {
        if (vis[i] == 0) res++;
        if (e[i].empty()) res += dis[i];
    }
    cout << res;

    return 0;
}

E. Trade Road

可以参考官方题解的证明思路,得到以下引理

不存在市场两两不相同的\(A,B,C,D\),使得商路\(\vec{AB},\vec{CD}\)同时存在

因此,最终的结果一定是有两种

  1. 所有商路要么从\(x\)出发,要么到达\(x\)。
  2. 以\(x\)为顶角的等腰三角形。

因此找到从每一个点出发的最远点,然后枚举\(x\)就好了,我这里找最远点采用了二分,而不是官解的双指针。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

#define int i64

using vi = vector<int>;

int K;

int dis(int x, int y) {
    return min(((x - y) % K + K) % K, ((y - x) % K + K) % K);
}

int norm(int x) {
    return (x % K + K) % K;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> K >> n;

    vi a(n + 1);
    map<int, int> idx;
    set<int> vis;
    for (int i = 1; i <= n; i++) {
        cin >> a[i], a[i]--, idx[a[i]] = i;
        vis.insert(a[i] - K - K);
        vis.insert(a[i] - K);
        vis.insert(a[i]);
        vis.insert(a[i] + K);
        vis.insert(a[i] + K + K);
    }
    vector<vi> e(n + 1);
    vector<map<int, int>> road(n + 1);
    vi cnt(n + 1);
    for (int i = 1; i <= n; i++) {
        set<int> b;
        int x = a[i] + K / 2;
        b.insert(norm(*vis.lower_bound(x)));
        b.insert(norm(*prev(vis.upper_bound(x))));
        x++;
        b.insert(norm(*vis.lower_bound(x)));
        b.insert(norm(*prev(vis.upper_bound(x))));

        int maxD = 0;
        for (auto j: b)
            maxD = max(maxD, dis(a[i], j));

        for (auto y: b)
            if (dis(a[i], y) == maxD) {
                int j = idx[y];
                e[i].push_back(j);
                cnt[j]++;
                road[i][j] = 1;
            }
    }

    int res = 0;
    for (int x = 1, ans; x <= n; x++) {
        ans = cnt[x];
        for (auto y: e[x])
            if (road[y][x] == 0) ans++;
        res = max(res, ans);

        if (e[x].size() == 2) {
            int y = e[x][0], z = e[x][1];
            if (road[y][z])
                res = max(res, 3ll);
        }
    }
    cout << res;
    return 0;
}

F. Try a try, AC is OK

与只会变小,所以序列最大值就是答案

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using vi = vector<int>;


void solve() {
    int n;
    cin >> n;
    vi a(n);
    for (auto &i: a) cin >> i;
    cout << ranges::max(a) << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}

G. Disappearing Number

一种类似数位 dp 的方法,枚举每一位的方案即可

#include <bits/stdc++.h>

using namespace std;

using i32 = int;
using i64 = long long;

#define int i64

using vi = vector<int>;

void solve() {
    int n, x;
    cin >> n >> x;
    int pre = 1, sum = 1;
    while (n) {
        int y = n % 10;
        if (y > x) y--;
        sum += y * pre;
        pre = pre * 9, n /= 10;

    }
    cout << sum << "\n";
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}

L. Chess

考虑到在任何进制下,个位数一定是成立的,且满足条件的\(y\)个位一定是非\(0\)的。

类似 bash 博弈,如果\(x\)的个位为 0 则一定无法一步拿完,同时如果个位不为 0 ,则一定可以通过一次操作使得个位为 0。因此如果\(x\)的个位为0,则先手一定必败。所以枚举进制,找到最小\(k\)进制使得\(x\)各个位不为 0 即可。

#include <bits/stdc++.h>

using namespace std;

using i32 = int;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int, int>;

void solve() {
    i64 n;
    cin >> n;
    for (int i = 2;; i++)
        if (n % i != 0) {
            cout << i << "\n";
            return;
        }
    return;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();


    return 0;
}

M. Window Decoration

一个正方形的面积为 \(2\),每一个相邻的正方形会公用\(0.5\)的面积,不会出现同一块被三个及以上的正方形覆盖的情况,因此简单容斥就好了

#include <bits/stdc++.h>

using namespace std;

using i32 = int;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int, int>;


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;

    vector<pii> a(n);
    for (auto &[x, y]: a)
        cin >> x >> y;

    sort(a.begin(), a.end());
    a.resize(unique(a.begin(), a.end()) - a.begin());

    double res = a.size() * 2;
    for (int i = 1; i < a.size(); i++) {
        auto [x, y] = a[i];
        for (int j = 0; j < i; j++) {
            auto [p, q] = a[j];
            if (abs(x - p) + abs(y - q) == 1) res -= 0.5;
        }
    }
    cout << fixed << setprecision(10) << res;

    return 0;
}

标签:Provincial,Contest,int,vi,cin,long,2024,vector,using
From: https://www.cnblogs.com/PHarr/p/18358908

相关文章

  • 2024“钉耙编程”中国大学生算法设计超级联赛(8)1006 cats 的最小生成树
    题目大意:给出有\(n\)个点\(m\)条边的图,接下来进行若干次操作,每次操作取出当前图的最小生成树,然后删去这些构成最小生成树的边,知道该图不连通,输出每条边在第几次操作时被删除思路:由于构成最小生成树的边数是\(n-1\)条边,所以最多操作次数为\(\lfloor\frac{m}{n-1}\rfloor\),每次......
  • IntelliJ IDEA【最新】2024终极版 下载安装教程,图文步骤详解
    文章目录软件介绍软件下载安装步骤ActivationMethod专栏推荐:超多精品软件(持续更新中…)软件介绍IntelliJIDEA是一款由JetBrains公司开发的集成开发环境(IDE),专为软件开发人员设计,尤其在Java编程领域享有极高的声誉,被认为是市场上最好的JavaIDE之一。以下是对In......
  • 2024年8月中国数据库排行榜:OceanBase攀升再夺冠,达梦跃入三甲关
    在这个炽热的季节,随着巴黎奥运会的盛大开幕,全球将目光聚集在了体育的无限魅力和竞技的巅峰对决上。如同奥运赛场上的激烈角逐,中国数据库界也上演着一场技术与创新的较量,各个数据库产品正在中国乃至全球舞台上展示着它们的实力和潜力。现在让我们共同盘点本月墨天轮社区中国数据库......
  • 2024-08-14:用go语言,给定两个长度分别为n和m的整数数组nums和changeIndices,下标从1开始
    2024-08-14:用go语言,给定两个长度分别为n和m的整数数组nums和changeIndices,下标从1开始。初始时,nums中所有下标均未标记。从第1秒到第m秒,每秒可以选择以下四种操作之一:1.选择范围[1,n]中一个下标i,将nums[i]减少1。2.将nums[changeIndices[s]]设为任意非负整数。3.选择范围......
  • CentOS 7 停服后(2024-06-30)升级最新的Linux 内核
     1、CentOS7更新 USTC的源sudosed-i.bak\-e's|^mirrorlist=|#mirrorlist=|g'\-e's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.ustc.edu.cn/centos-vault/centos|g'\/etc/yum.repos.d/CentOS-Base.repo 2......
  • DeiT-LT:印度科学院提出针对长尾数据的`DeiT`升级模型 | CVPR 2024
    DeiT-LT为ViT在长尾数据集上的应用,通过蒸馏DIST标记引入CNN知识,以及使用分布外图像并重新加权蒸馏损失来增强对尾类的关注。此外,为了减轻过拟合,论文建议用经过SAM训练的CNN教师进行蒸馏,促使所有ViT块中DIST标记学习低秩泛化特征。经过DeiT-LT的训练方案,DIST标记成为尾类的专家,分......
  • StarNet:关于 Element-wise Multiplication 的高性能解释研究 | CVPR 2024
    论文揭示了staroperation(元素乘法)在无需加宽网络下,将输入映射到高维非线性特征空间的能力。基于此提出了StarNet,在紧凑的网络结构和较低的能耗下展示了令人印象深刻的性能和低延迟来源:晓飞的算法工程笔记公众号论文:RewritetheStars论文地址:https://arxiv.org/abs/240......
  • H7-TOOL混合脱机烧录以及1拖4不同的通道烧录不同的程序操作说明(2024-08-07)
     【应用场景】原本TOOL的1拖4是用于同时烧录相同程序给目标板,但有时候一个板子上有多个不同的MCU,客户希望仅通过一个TOOL就可以完成对板子上多个MCU的烧录,也就是1拖4不同的通道烧录不同的程序,此贴为此制作。【实验目标】由于这个属于定制需求,需要简单修下目标文件,后面升......
  • [权威出版|稳定检索]2024年航空航天、机械与控制工程国际会议(AMCE 2024)
    2024年航空航天、机械与控制工程国际会议2024InternationalConferenceonAerospace,MechanicalandControlEngineering【1】大会信息会议名称:2024年航空航天、机械与控制工程国际会议会议简称:AMCE2024大会时间:请查看官网大会地点:中国·温州截稿时间:请查看官网......
  • 高危漏洞CVE-2024-38077的修复指南
    “根据2024年8月9日,国家信息安全漏洞共享平台(CNVD)收录了Windows远程桌面许可服务远程代码执行漏洞(CNVD-2024-34918,对应CVE-2024-38077)。未经身份认证的攻击者可利用漏洞远程执行代码,获取服务器控制权限。目前,该漏洞的部分技术原理和概念验证伪代码已公开,厂商已发布安......