首页 > 其他分享 >The 2023 Guangdong Provincial Collegiate Programming Contest

The 2023 Guangdong Provincial Collegiate Programming Contest

时间:2023-05-31 12:33:05浏览次数:40  
标签:Provincial cnt return tire Contest int res Programming vector

A - 算法竞赛

#include <bits/stdc++.h>
using namespace std;
#define int long long

void solve(){
    int st , n , ed;
    cin >> st >> n;
    map<int,int> cnt;
    for( int i = 1 , x ; i <= n ; i ++ ){
        cin >> x;
        cnt[x] ++;
    }
    cin >> ed;
    int res = 0;
    for( int i = st ; i <= ed ; i ++ ){
        if( cnt[i] ) continue;
        res ++;
    }
    cout << res << "\n";
    return ;
}

int32_t main() {
    int t;
    cin >> t;
    for( ; t ; t -- ){
        solve();
    }
    return 0;
}

B - 基站建设

\(f(i)\)表示前\(i\)个基站\(i\)必选的情况下的最小成本\(f(i) =\min f(j) + a_i\)

注意\([j+1,i-1]\)中不能有任何一个完整区间,所以我们要计算出\(lim(i)\)表示\([lim(i),i]\)中没有完整区间的最小值。那么\(j\ge lim(i-1)-1\)

然后再用单调队列优化一下dp

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    // 在 n+1 添加一个花费为 0 的基站,并添加一个 [n+1,n+1] 的需求区间这样 f[n+1] 就是答案
    a.push_back(0), n++;
    int m;
    cin >> m;
    vector<vector<int>> b(n+1);
    // 里面的负数 -j 表示有一个需求区间是 [i, j]
    // 里面是正数 j 表示有一个需求区间是 [j, i]
    for (int i = 1, l, r; i <= m; i++)
        cin >> l >> r, b[l].push_back(-r), b[r].push_back(l);
    b[n].push_back( -n) ,b[n].push_back(n);

    vector<int> lim(n+1);
    for( int l = 1 , r = 1 , cnt = 0; l <= n ; r ++ ){
        for( auto x : b[r] )
            if( x > 0 && x >= l ) cnt ++;
        while( cnt > 0 && l <= r ){
            for( auto x : b[l] )
                if( x < 0 && -x <= r ) cnt --;
            l ++;
        }
        lim[r] = l;
    }
    vector<int> f( n+1 );
    deque<int> q;
    f[1] = a[1] , q.push_back(0) , q.push_back(1);
    for( int r = 2 , l ; r <= n ; r ++ ){
        l = lim[r-1] - 1;
        while( q.front() < l ) q.pop_front();
        f[r] = f[ q.front() ] + a[r];
        while( !q.empty() && f[ q.back() ] >= f[r] ) q.pop_back();
        q.push_back(r);
    }
    cout << f[n] << "\n";
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    for (; t; t--)
        solve();
    return 0;
}

C - 市场交易

按照价格排序后贪心购买

#include <bits/stdc++.h>
using namespace std;

#define int long long

void solve(){
    int n;
    cin >> n;
    vector<pair<int,int>> a(n);
    for( auto & [x , y ] : a )
        cin >> x >> y;
    sort( a.begin(), a.end() );

    int res = 0;
    for( int l = 0 , r = n-1 , t ; l < r ; ){
        t = min( a[l].second , a[r].second );
        res += (a[r].first - a[l].first) * t;
        a[l].second -= t , a[r].second -= t;
        if( a[l].second == 0 ) l ++;
        if( a[r].second == 0 ) r --;
    }
    cout << res << "\n";
    return ;
}

int32_t main() {
    ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
    int t;
    cin >> t;
    for( ; t ; t -- ){
        solve();
    }
    return 0;
}

D - 新居规划

把人按照\(a_i-b_i\)从小到大排序,排序后越靠前的人越喜欢独居,越靠后的人越喜欢群居,然后分别计算前缀独居贡献和和后缀群居贡献和。最后枚举出独居的人数即可。

#include <bits/stdc++.h>
using namespace std;

#define int long long

void solve(){
    int n , m;
    cin >> n >> m;

    vector<pair<int,int>> a(n);
    for( auto &[x,y] : a )
        cin >> x >> y;
    sort( a.begin(), a.end() , [](pair<int,int> x , pair<int,int>y){
        return x.first-x.second < y.first - y.second;
    } );
    vector<int> p(n+1) , q(n+1);

    for( int i = 1 ; i <= n ; i ++ )
        p[i] = p[i-1] + a[i-1].second;

    q[n] = a[n-1].first;
    for( int i = n-1 ; i >= 1 ; i -- )
        q[i] = q[i+1] + a[i-1].first;

    reverse(q.begin()+1, q.end());

    int res = 0;
    for( int i = 0 , j = n ; i <= n ; i ++ , j -- ){
        if( i * 2 + j > m ) break;
        if( j < 2 ) continue;
        res = max( res , p[i] + q[j] );
    }
    if( 2 * n - 1 <= m ) res = max( res , p[n] );
    cout << res << "\n";


    return ;
}

int32_t main() {
    ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
    int t;
    cin >> t;
    for( ; t ; t -- ){
        solve();
    }
    return 0;
}

E - 新杯质问

把所有的字符串都插入到 Tire 上,然后贪心的选择即可,首先给每个分支都任一选择一个,这样的话 LCP不会变化。如果不能满足选择的需求的话,就按照字典序贪心的选择,最后一个选到的就是 LCP 新增的一位。

#include <bits/stdc++.h>

using namespace std;

#define int long long

vector<int> val;

struct node {
    vector<int> to;
    int g, cnt;
    node() {
        to = vector<int>(26, -1);
        cnt = 0, g = -1;
    }
};

vector<node> tire;

string res;

void dfs(int x) {
    if (tire[x].cnt) val[x] = tire[x].cnt;
    for (auto y: tire[x].to) {
        if (y == -1) continue;
        dfs(y);
        val[x] += val[y];
    }
    return;
}

void calc(int x, int k) {
    if (tire[x].g != -1) res += (char) (tire[x].g + 'a');
    if( tire[x].cnt ) k -= tire[x].cnt;
    if( k <= 1 ) return ;
    int cnt = 26;
    for (auto y: tire[x].to)
        cnt -= (y == -1);
    if (cnt >= k) return;
    for (auto y: tire[x].to) {
        if (y == -1) continue;
        cnt--;
        if (cnt + val[y] < k) k -= val[y];
        else {
            k -= cnt;
            calc(y, k);
            return;
        }
    }
}

void solve() {
    int n, m;
    cin >> n >> m;
    tire = vector<node>(1, node());
    for (int i = 1, t; i <= n; i++) {
        string s;
        cin >> s;
        t = 0;
        for (int i = 0, j; i < s.size(); i++) {
            j = s[i] - 'a';
            if (tire[t].to[j] == -1) {
                tire[t].to[j] = tire.size();
                tire.push_back(node());
                tire.back().g = j;
            }
            t = tire[t].to[j];
        }
        tire[t].cnt ++;
    }
    val = vector<int>(tire.size());
    dfs(0);
    res = "";
    calc(0, m);
    if (res == "") res = "EMPTY";
    cout << res << "\n";
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    for (; t; t--) {
        solve();
    }
    return 0;
}

I - 路径规划

二分答案,二分\(mex\)的值,则\([0,mex-1]\)都应该在序列中,这样这些点的下标按照\(x\)升序排列后,\(y\)也应该是升序排序。所以\(O(n\log n )\)的校验即可

#include <bits/stdc++.h>

using namespace std;


void solve() {
    int n, m;
    cin >> n >> m;
    vector<pair<int, int>> a(n * m);
    for( int i = 1 ; i <= n ; i ++ )
        for( int x , j = 1 ; j <= m ; j ++ )
            cin >> x , a[x] = make_pair( i , j );

    auto check =[a]( int x ){
        if( x < 0 ) return true;
        auto b = vector<pair<int,int>>( a.begin() , a.begin() + x );
        sort( b.begin() , b.end() );
        for( int i = 1 ; i < b.size() ; i ++ )
            if( b[i].second < b[i-1].second ) return false;
        return true;
    };

    int l = 0 , r = n*m , mid ,res = 0;
    while( l <= r ){
        mid = ( l + r ) >> 1;
        if( check( mid ) ) res = mid , l = mid + 1;
        else r = mid - 1;
    }
    cout << res << "\n";
    return;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    for (; t; t--) {
        solve();
    }
    return 0;
}

K - 独立钻石

直接 dfs,暴力的枚举棋子和方向即可,\(O(6!\times 4)\)

#include <bits/stdc++.h>

using namespace std;

int res, n, m;

const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};

void dfs(int k, vector<vector<int>> g) {
    res = min(res, k);
    if( k == 1 ) return ;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (g[i][j] == 0) continue;
            for (int l = 0, ax, ay, bx, by; l < 4; l++) {
                ax = i + dx[l], ay = j + dy[l];
                if (ax < 0 || ay < 0 || ax >= n || ay >= m || g[ax][ay] == 0) continue;
                bx = ax + dx[l], by = ay + dy[l];
                if (bx < 0 || by < 0 || bx >= n || by >= m || g[bx][by] == 1) continue;
                g[i][j] = 0, g[ax][ay] = 0, g[bx][by] = 1;
                dfs(k-1, g);
                g[i][j] = 1, g[ax][ay] = 1, g[bx][by] = 0;
            }
        }
    }
}

void solve() {
    int k;
    cin >> n >> m >> k;
    vector<vector<int>> g(n, vector<int>(m, 0));
    res = k;
    for (int x, y; k; k--)
        cin >> x >> y , x -- , y -- ,  g[x][y] = 1;
    dfs(res, g);
    cout << res << "\n";
    return;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    for (; t; t--) {
        solve();
    }
    return 0;
}

标签:Provincial,cnt,return,tire,Contest,int,res,Programming,vector
From: https://www.cnblogs.com/PHarr/p/17445779.html

相关文章

  • Comet OJ - Contest #13[A-D]
    题目链接:https://www.cometoj.com/contest/71/problems A.「壶中的大银河」水题B.「龙颈之玉-五色的弹丸-」用一个双向队里维护一下贪吃蛇某个点的前一个位置方向是啥就好了#include<bits/stdc++.h>#definexfirst#defineysecond#defineinf0x3f3f3f3fusingnamespaces......
  • Comet OJ - Contest #3 A-D
    题目链接:https://www.cometoj.com/contest/38/problems A.比赛暴力枚举+排序#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;constintmx=500+10;intn,m,a[mx];llb[mx*mx];intmain(){ intsiz=0; scanf(......
  • 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 201
    题目链接:https://vjudge.net/contest/339284#overview A.Numbers待做B.BrokenWatchs=input()s=s.split("")A,B,C,N=list(map(int,s))n=(N-1)//2ret=N*N*N-3*N*(n)*(n-1)-N-3*N*(N-1)ans=retmod=1<<64if(A==BandB==C):......
  • Programming: loop
     whileinitialize testchangeoperationchange,test,operation'sorderwillaffectthefirstlinenumber......
  • AtCoder Beginner Contest 258 Ex Odd Steps
    洛谷传送门AtCoder传送门不错的矩阵快速幂优化dp练习题。考虑一个朴素dp,\(f_i\)为组成和为\(i\)且用到的数都是奇数的方案数。有转移:\[f_i=\begin{cases}\sum\limits_{j=0}^{i-1}[i\bmod2\nej\bmod2]f_j&i\notinA\\0&i\inA\end{cases}\]考虑前......
  • AtCoder Beginner Contest 289(E,F)
    AtCoderBeginnerContest289(E,F)E(dijkstra)E这个题的大意就是有两个人,一个人在点\(1\),一个人在点\(n\),现在两个人要同时走(题目给出了点和边,还有每一个点的颜色),但是他们的下一步要到的点需要是颜色不同的,问\(1\)点出发的和\(n\)点出发的同时达到对方的起点的最短路径时哪......
  • AtCoder Beginner Contest 303
    A-SimilarString(abc303a)题目大意给定两个字符串,问这两个字符串是否相似。两个字符串相似,需要每个字母,要么完全相同,要么一个是1一个是l,要么一个是0一个是o解题思路按照题意模拟即可。可以将全部1换成l,全部0换成o,再判断相等。神奇的代码#include<bits/stdc++.h>us......
  • AtCoder Regular Contest 153 D Sum of Sum of Digits
    洛谷传送门AtCoder传送门又浪费一道好题我首先想的是,\(x\)显然最优取某些\(a_i\)往前进位时的值。然后就误以为\(x\)的取值是\(O(n\log_{10}V)\)的了……既然没发现什么性质,那就直接dp吧!设\(f_{d,i}\)为从低到高前\(d\)位,所有\(a_i\)进位之和为\(i\)。然......
  • AtCoder Regular Contest 161
    PrefaceARC战俘闪总出列这场一上来就感觉状态不太对,先是A顺序敲反WA了一发,然后C题看到秒出一个贪心然后也WA了看一眼榜发现D过的比C多,然后跑去把D写了,中间还偷偷挂了两发最后50min回去沉淀C题,结果换了两种写法都还是一样的挂,后面发现想法还是有纰漏总结:彩笔A-MakeM考虑......
  • Focus On 3D Terrain Programming三维地形渲染-Trent Polack-2003
    前言:你有多少次访问过你最喜欢的编程论坛或邮件列表,并对大量关于地形渲染算法的帖子感到惊讶,这些帖子似乎从各个角度向你袭来?地形渲染似乎是当今业余程序员最喜欢的主题;它是一个很好的门户网站,可以了解更高要求的问题及其解决方案。然而,地形渲染决不是一个简单的问题,特定的解决方......