ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kickstart 2021 round A

2021-05-15 19:03:13  阅读:175  来源: 互联网

标签:kickstart int cin ++ vector grid 2021 dx round


刚开始刷,记录一下,都是在练习模式下做的

K-Goodness String

 

 代码:

#include <iostream>
#include <string>
using namespace std;
int main(){
    int t;
    cin >> t;
    for(int j = 1; j <= t; ++j){
        int n, k;
        cin >> n >> k;
        string s;
        cin >> s;
        int score = 0;
        for(int i = 1; i <= n / 2; ++i){
            if(s[i - 1] != s[n - i]) score++;
        }
        cout << "Case #" << j << ": " << abs(k - score) << endl;
    }
    return 0;
}

L Shaped Plots

 

思路:

考虑将每一个点作为L形状的端点,在8种情况中取四种情况避免重复计算,想来想去把自己绕晕了,参考题解将每一个点作为拐点瞬间清晰了许多

代码:

#include<iostream>
#include<vector>
using namespace std;
int cal(int se, int le1, int le2) {
    int res = 0;
    int maxi = le1 > le2 ? le1 : le2;
    for (int i = 2; i <= se && i + i <= maxi; ++i) {
        res += (i + i <= le1);
        res += (i + i <= le2);
    }
    return res;
}
int main() {
    int t;
    cin >> t;
    for (int caseid = 1; caseid <= t; caseid++) {
        int r, c;
        cin >> r >> c;
        vector<vector<int>> grid(r, vector<int>(c, 0));
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) cin >> grid[i][j];
        }
        int res = 0;
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                if (!grid[i][j]) continue;
                int up = 1, down = 1, left = 1, right = 1;
                for (int k = i - 1; k >= 0; --k) {
                    if (grid[k][j]) up++;
                    else break;
                }
                for (int k = i + 1; k < r; ++k) {
                    if (grid[k][j]) down++;
                    else break;
                }
                for (int k = j - 1; k >= 0; --k) {
                    if (grid[i][k]) left++;
                    else break;
                }
                for (int k = j + 1; k < c; ++k) {
                    if (grid[i][k]) right++;
                    else break;
                }
                if (up > 1) res += cal(up, left, right);
                if (down > 1) res += cal(down, left, right);
                if (left > 1) res += cal(left, up, down);
                if (right > 1) res += cal(right, up, down);
            }
        }
        cout << "Case #" << caseid << ": " << res << endl;
    }
}

Rabbit House

 

 思路:

首先很自然想到使用优先队列,从高度最大的cell开始更新它四周的cell,但在如何更新上犯了难,参考题解,直接插入配合状态数组

代码:

#include<iostream>
#include<queue>
using namespace std;
int main() {
    int t;
    cin >> t;
    vector<vector<int>> dir = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    for (int caseid = 1; caseid <= t; ++caseid) {
        int r, c;
        cin >> r >> c;
        long long res = 0;
        
        priority_queue<pair<long long, pair<int, int>>> pq;
        vector<vector<long long>> grid(r, vector<long long>(c, 0));
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                cin >> grid[i][j];
                pq.push({ grid[i][j], {i, j} });
            }
        }
        vector<vector<bool>> st(r, vector<bool>(c, false));
        while (pq.size()) {
            auto i = pq.top();
            pq.pop();
            long long h = i.first;
            auto j = i.second;
            int x = j.first, y = j.second;
            if (st[x][y]) continue;
            st[x][y] = true;
            for (auto d : dir) {
                int dx = x + d[0];
                if (dx < 0 || dx >= r) continue;
                int dy = y + d[1];
                if (dy < 0 || dy >= c) continue;
                if(st[dx][dy]) continue;
                if (grid[dx][dy] < h - 1) {
                    res += h - 1 - grid[dx][dy];
                    grid[dx][dy] = h - 1;
                    pq.push({ h - 1, {dx, dy} });
                }
            }
        }
        cout << "Case #" << caseid << ": ";
        cout << res << endl;
    }
}

Checksum

 

思路:

看了半天题解才懂,直接复制过来,对于任何一行或一列,如果我们只有一个值是未知的,我们可以用所有其他值异或上异或和便可以求解这个值;如果有至少两个位置未知,那么我们便无法求解。考虑每一个A[i][j] = -1的位置,我们每一行和每一列最多有1个值是可以通过当列(行)的异或值自己求出来的,那么我们应该尽量选取B[i][j]更大的值来节省时间。怎样找到这样的点的集合呢?由于每列(行)最多使用一次,我们可以把每一行(列)看成一个点,可以把每个A[i][j]看成是把第i行和第j列连接起来的边,在生成图中找最大生成树,组成最大生成树的边集就是我们要找的点集。答案为所有A[i][j]=-1的B[i][j]之和减去最大生成树的边权和。

代码:

#include<iostream>
#include<vector>
using namespace std;
const int N = 1010;
int p[N];
int find(int x){
    if(x != p[x]) p[x] = find(p[x]);
    return p[x];
}
int main(){
    int T;
    cin >> T;
    for(int t = 1; t <= T; ++t){
        int n;
        cin >> n;
        vector<vector<int>> a(n, vector<int>(n, 0));
        vector<vector<int>> b(n, vector<int>(n, 0));
        vector<int> r(n, 0);
        vector<int> c(n, 0);
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j) cin >> a[i][j];
        }
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j) cin >> b[i][j];
        }
        for(int i = 0; i < n; ++i) cin >> r[i];
        for(int i = 0; i < n; ++i) cin >> c[i];
        vector<vector<int>> vec(1001);
        int sumcost = 0;
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                if(a[i][j] == -1){
                    sumcost += b[i][j];
                    vec[b[i][j]].push_back(i);
                    vec[b[i][j]].push_back(j + n);
                }
            }
        }
        for(int i = 0; i < n + n; ++i) p[i] = i;
        for(int val = 1000; val >= 0; --val){
            auto v = vec[val];
            for(int i = 0; i < v.size(); i += 2){
                int x = find(v[i]), y = find(v[i + 1]);
                if(x != y){
                    sumcost -= val;
                    p[x] = y;
                }
            }
        }
        cout << "Case #" << t << ": " << sumcost << endl;
    }
}

 

标签:kickstart,int,cin,++,vector,grid,2021,dx,round
来源: https://www.cnblogs.com/clarathebest/p/14772277.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有