zoukankan      html  css  js  c++  java
  • The 18th Zhejiang Provincial Collegiate Programming Contest 补题记录(ACFGJLM)

    补题链接:Here

    A. League of Legends

    签到题,求和判断即可

    ll suma, sumb;
    void solve() {
        ll x;
        for (int i = 1; i <= 5; ++i)cin >> x, suma += x;
        for (int i = 1; i <= 5; ++i)cin >> x, sumb += x;
        if (suma < sumb) cout << "Red
    "; // 注意这里要写suma<sumb
        else cout << "Blue
    ";
    }
    

    C. Cube

    给定 8 个点(三维XYZ),判断是否是正方体


    判断是否有 12 个相等的棱, 12 个相等的面对角线,4 个相等的体对角线,以及棱,面对角线和体对角线可以形成直角三角形(满足勾股定理)就行了。

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const ll inf = 0x3f3f3f3f3f3f3f3f;
    struct Point {
        int x, y, z;
        Point() {}
        Point(int x, int y, int z): x(x), y(y), z(z) {}
        bool operator<(const Point b) const {
            if (x != b.x) return x < b.x;
            if (y != b.y) return y < b.y;
            if (z != b.z) return z < b.z;
            return 0;
        }
    };
    
    vector<Point>a;
    set<Point>a4, ano4;
    ll maxDis;
    
    ll getDis(Point a, Point b) {
        return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z);
    }
    
    void init() {
        maxDis = -1;
        a4.clear(), ano4.clear();
    }
    
    bool sol() {
        init();
        for (int i = 0; i < 8; ++i)
            for (int j = 0; j < i; ++j)
                if (!(a[i] < a[j]) and !(a[j] < a[i]))return false;
        vector<ll>diss;
        for (int i = 0; i < 8; ++i)
            for (int j = 0; j < i; ++j)
                diss.push_back(getDis(a[i], a[j]));
        sort(diss.begin(), diss.end());
        for (int i = 0; i < 12; ++i)
            for (int j = 0; j < j; ++j)
                if (diss[i] != diss[j])return false;
        for (int i = 0; i < 12; ++i)
            for (int j = 0; j < j; ++j)
                if (diss[12 + i] != diss[12 + j])return false;
        for (int i = 0; i < 4; ++i)
            for (int j = 0; j < i; ++j)
                if (diss[24 + i] != diss[24 + j])return false;
        if (diss[0] + diss[12] != diss[24]) return 0;
        return true;
    }
    
    void solve() {
        a.resize(8);
        for (int i = 0; i < 8; ++i) {
            cin >> a[i].x >> a[i].y >> a[i].z;
        }
        cout << (sol() ? "YES
    " : "NO
    ");
    }
    int main() {
        ios::sync_with_stdio(false), cin.tie(nullptr);
        int _;
        for (cin >> _; _--;) solve();
        return 0;
    }
    

    F. Fair Distribution

    (n) 只能减少(并且 (n) 不能为 (0)),(m) 只能增加,求出最终达到状态使 (n*k=m) 时,(n) 减少的值与 (m) 增加的值之和最小。


    数论题(分治处理),类似某场ARC的题

    • (n >= m) 时,不难发现输出 (n-m) 即可

    • (n < m) 时,我们可以枚举n来求出最终答案,但是枚举并不是一个一个加,因为中间的值在跳跃,所以我们每次确定一个 (l)(r = min(n,(m - 1)/((m-1)/l))) ,而下个 (l = r + 1)

      此时 (k = ⌊frac{m-1}i*i⌋)

    using ll = long long;
    void solve() {
        ll n, m; cin >> n >> m;
        if (n > m)cout << n - m << "
    ";
        else {
            ll cnt = 0x3f3f3f3f;
            for (ll l = 1, r; l <= n; l = r + 1) {
                r = min(n, (m - 1) / ((m - 1) / l));
                cnt = min(cnt, (m - 1) / l * l);
            }
            cout << cnt + n - m << '
    ';
        }
    }
    

    G. Wall Game

    题意待补


    // 待补#include <bits/stdc++.h>
    #define PI atan(1.0)*4
    #define rp(i,s,t) for (register int i = (s); i <= (t); i++)
    #define RP(i,t,s) for (register int i = (t); i >= (s); i--)
    #define sc(x) scanf("%d",&x)
    #define scl(x) scanf("%lld",&x)
    #define ll long long
    #define ull unsigned long long
    #define mst(a,b) memset(a,b,sizeof(a))
    #define lson rt<<1,l,m
    #define rson rt<<1|1,m+1,r
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define m_p make_pair
    #define p_b push_back
    #define ins insert
    #define era erase
    #define INF 0x3f3f3f3f
    #define inf 0x3f3f3f3f3f3f3f3f
    #define dg if(debug)
    #define pY puts("YES")
    #define pN puts("NO")
    #define outval(a) cout << "Debuging...|" << #a << ": " << a << "
    ";
    #define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"	"<< #b << ": " << b << "
    ";
    #define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"	"<< #b << ": " << b <<"	"<< #c << ": " << c << "
    ";
    using namespace std;
    int debug = 0;
    ll gcd(ll a, ll b) {
        return b ? gcd(b, a % b) : a;
    }
    ll lcm(ll a, ll b) {
        return a / gcd(a, b) * b;
    }
    inline int read() {
        int s = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            s = s * 10 + ch - '0';
            ch = getchar();
        }
        return s * f;
    }
    const int N = 5e5 + 7;
    int fa[N];
    int w[N];
    map<pii, int> mp;
    int dir[6][2] = {0, 1, 1, 0, 1, -1, 0, -1, -1, 0, -1, 1};
    int find(int x) {
        return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
    }
    void solve() {
        int n = read();
        int tot = 0;
        while (n--) {
            int op = read(), x = read(), y = read();
            if (op == 1) {
                mp[m_p(x, y)] = ++tot;
                fa[tot] = tot;
                w[tot] = 6;
                int sum = 0;
                int minus = 0;
                int cnt = 0;
                set<int> ss;
                vector<pii> vv;
                rp(k, 0, 5) {
                    int nx = x + dir[k][0];
                    int ny = y + dir[k][1];
                    if (mp.find(m_p(nx, ny)) == mp.end()) continue;
                    int id = find(mp[m_p(nx, ny)]);
                    vv.push_back(m_p(k, id));
                    if (ss.find(id) != ss.end()) cnt++;
                    else {
                        cnt++;
                        sum += w[id];
                        ss.insert(id);
                    }
                }
                int len = vv.size();
                rp(k, 0, len - 1) {
                    rp(j, 0, len - 1) {
                        if (vv[k].first == 0 && vv[j].first == 1 && vv[k].second != vv[j].second) minus++;
                        if (vv[k].first == 1 && vv[j].first == 2 && vv[k].second != vv[j].second) minus++;
                        if (vv[k].first == 2 && vv[j].first == 3 && vv[k].second != vv[j].second) minus++;
                        if (vv[k].first == 3 && vv[j].first == 4 && vv[k].second != vv[j].second) minus++;
                        if (vv[k].first == 4 && vv[j].first == 5 && vv[k].second != vv[j].second) minus++;
                        if (vv[k].first == 5 && vv[j].first == 0 && vv[k].second != vv[j].second) minus++;
                    }
                }
                for (auto val : ss) {
                    // cout<<val<<" ";
                    fa[val] = tot;
                }
                // cout<<endl;
                w[tot] = sum + w[tot] - 2 * cnt - 2 * minus;
                // cout<<w[tot]<<endl;
                // outval3(sum,cnt,minus);
            } else {
                cout << w[find(mp[m_p(x, y)])] << endl;
            }
        }
        // for(auto val:mp){
        // pii t=val.first;
        // outval3(t.first,t.second,find(mp[t]));
        // }
    }
    int main() {
        //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
        //debug = 1;
    #endif
        //time_t beg, end;
        //if(debug) beg = clock();
        solve();
        /*
        if(debug) {
            end = clock();
            printf("time:%.2fs
    ", 1.0 * (end - beg) / CLOCKS_PER_SEC);
        }
        */
        return 0;
    }
    

    J. Grammy and Jewelry

    题意待补


    算是比较套路的题。

    根据贪心的原则,我们每次取一个宝珠后应该立马返回到原点。

    而我们到这个宝珠的位置走的路和返回时走的路应该是最短路。

    转换一下就是我们要取一个价值为 (a[i]) 的宝珠,需要消耗容量为(2∗dis[i]) 的时间((dis[i]) 表示从 (1)(i) 的最短路)。

    这样就转换成了经典的完全背包问题。

    关于背包问题不懂的可以看经典的背包九讲。

    const int N = 3010, inf = 0x3f3f3f3f;
    vector<int>e[N];
    struct node {
        int u, w;
        node() {}
        node(int u, int w): u(u), w(w) {}
        friend bool operator <(node a, node b) {
            return a.w > b.w;
        }
    };
    
    int a[N], dis[N], vis[N], dp[N];
    int n, m, t;
    void Dijlstra() {
        priority_queue<node> q;
        for (int i = 1; i <= n; ++i)dis[i] = inf;
        q.push(node{1, 0});
        dis[1] = 0;
        memset(vis, 0, sizeof vis);
        while (!q.empty()) {
            node t = q.top();
            q.pop();
            vis[t.u] = 1;
            int u = t.u;
            int w = t.w;
            // cout << u << " " << w << endl;
            for (auto v : e[u]) {
                // cout << v << " " << dis[v] << endl;
                if (!vis[v] && dis[v] > w + 1) {
                    dis[v] = w + 1;
                    q.push(node{v, dis[v]});
                }
            }
        }
    }
    void solve() {
        cin >> n >> m >> t;
        for (int i = 2; i <= n; ++i)cin >> a[i];
        for (int i = 1; i <= m; ++i) {
            int u, v; cin >> u >> v;
            if (u == v)continue;
            e[u].push_back(v);
            e[v].push_back(u);
        }
        Dijlstra();
        for (int i = 1; i <= n; ++i)
            for (int j = dis[i] * 2; j <= t; ++j)
                dp[j] = max(dp[j], dp[j - dis[i] * 2] + a[i]);
        for (int i = 1; i <= t; ++i)cout << dp[i] << (i == t ? "
    " : " ");
    }
    

    L. String Freshman

    读了半天题,结果题意有问题。。。

    给的字符串应该是匹配串。


    因此我们判断一下是否存在前缀子串的最长公共前后缀长度不为 (0)(即 next 数组不为 (0) )。

    更简单的做法就是判断是否有字符和第一个字符相等即可。

    void solve() {
        int n; string s;
        cin >> n >> s;
        for (int i = 1; i <= n - 1; ++i)
            if (s[i] == s[0]) {
                cout << "Wrong Answer
    ";
                return ;
            }
        cout << "Correct
    ";
    }
    

    M. Game Theory

    输出 0.0000 即可。

    首先我们知道每个学生是不知道 (Grammy) 的选择,而又因为学生每次都是最优的选择,因此我们可以先算出一个学生在 ([1 ,20]) 选择一个数后赢的分数的期望,每次都选择这(20) 个数中期望最大的即可。
    我们写出计算期望的代码可以发现,每个数赢的分数的期望都是 (0)

    而学生和 (Grammy) 的分数是互补的,只有一个输了,另一个赢了的情况

    所以 (Grammy) 胜利的期望也是 (0)

    void solve() {
        int n; cin >> n;
        cout << fixed << setprecision(4) << 0.0;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    关于路径的小知识点
    转发与重定向
    一种反复的读写文件的方法
    文字排版reportlab
    Qgis中插件的安装位置
    spyder打开文件假死解决
    地图跳跃-超级码力
    尾部的零
    一探torch.nn究竟“What is torch.nn really?”
    KAZE特征和各向异性扩散滤波
  • 原文地址:https://www.cnblogs.com/RioTian/p/14850604.html
Copyright © 2011-2022 走看看