2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)

\(2019-2020\ ACM-ICPC\ Brazil\ Subregional\ Programming\ Contest\)

\(A.Artwork\)

并查集,把检测区域能在一起的检测器放在一个并查集里,然后判断是否有一个集合能够封住左边和上边的其中一个还有右边和下边的其中一个即可

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1111;
const int INF = 0x3f3f3f3f;
int n,m,k,root[MAXN],tot;
pair<pair<int,int>,int> sensor[MAXN];
vector<int> SET[MAXN];
map<int,int> mp;
int findx(int x){
    if(x!=root[x]) root[x] = findx(root[x]);
    return root[x];
}
int dist(const pair<int,int> &A, const pair<int,int> &B){
    return (A.first-B.first)*(A.first-B.first)+(A.second-B.second)*(A.second-B.second);
}
int main(){
    scanf("%d %d %d",&n,&m,&k);
    for(int i = 1; i <= k; i++) scanf("%d %d %d",&sensor[i].first.first,&sensor[i].first.second,&sensor[i].second);
    for(int i = 1; i <= k; i++) root[i] = i;
    for(int i = 1; i <= k; i++) for(int j = i+1; j <= k; j++){
        int fa = findx(i);
        int fb = findx(j);
        if(fa==fb) continue;
        if((sensor[i].second+sensor[j].second)*(sensor[i].second+sensor[j].second)>=dist(sensor[i].first,sensor[j].first)){
            root[fa] = fb;
        }
    }
    for(int i = 1; i <= k; i++){
        if(!mp.count(findx(i))) mp.insert(make_pair(findx(i),++tot));
        SET[mp.at(findx(i))].emplace_back(i);
    }
    bool ok = true;
    for(int i = 1; i <= tot; i++){
        int u = -INF, d = INF, l = INF, r = -INF;
        for(auto p : SET[i]){
            u = max(u,sensor[p].first.second+sensor[p].second);
            d = min(d,sensor[p].first.second-sensor[p].second);
            l = min(l,sensor[p].first.first-sensor[p].second);
            r = max(r,sensor[p].first.first+sensor[p].second);
        }
        if((u>=m||l<=0)&&(d<=0||r>=n)){
            ok = false;
            break;
        }
    }
    puts(ok?"S":"N");
    return 0;
}

\(B.Buffoon\)

签到

\(C.Crossings\ With\ Danger\)

\(D.Denouncing Mafia\)

树形DP+优先队列 对于每个节点记录它的最深节点的位置,把链长为关键字丢到优先队列中,每次找最长的没有被遍历过的链

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n,m,par[MAXN],depth[MAXN],vis[MAXN];
vector<int> G[MAXN];
priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,less<pair<int,pair<int,int>>>> que;
int dfs(int u){
    depth[u] = depth[par[u]]+1;
    int maxdep = u;
    for(int v : G[u]){
        int p = dfs(v);
        maxdep = depth[maxdep]<depth[p]?p:maxdep;
    }
    que.push(make_pair(depth[maxdep]-depth[u]+1,make_pair(maxdep,u)));
    return maxdep;
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i = 2; i <= n; i++){
        scanf("%d",&par[i]);
        G[par[i]].emplace_back(i);
    }
    dfs(1);
    int ans = 0;
    while(!que.empty()&&m){
        auto p = que.top();
        que.pop();
        if(vis[p.second.second]) continue;
        m--;
        ans += p.first;
        while(p.second.first!=par[p.second.second]){
            vis[p.second.first] = 1;
            p.second.first = par[p.second.first];
        }
    }
    printf("%d\n",ans);
    return 0;
}

\(E.Exhibition\ of\ Clownfish\)

\(F.Forests\ in\ Danger\)

\(G.Getting\ Confidence\)

将乘法变成对数的加法然后就是KM匹配的模板了

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 111;
const int INF = 0x3f3f3f3f;
int n,LX[MAXN],LY[MAXN],visx[MAXN],visy[MAXN],match[MAXN],slack[MAXN],G[MAXN][MAXN];
bool dfs(int x){
    visx[x] = 1;
    for(int y = 1; y <= n; y++){
        if(visy[y]) continue;
        int gap = LX[x] + LY[y] - G[x][y];
        if(!gap){
            visy[y] = 1;
            if(match[y]==-1||(!visx[match[y]]&&dfs(match[y]))){
                match[y] = x;
                return true;
            }
        }
        else slack[y] = min(slack[y],gap);
    }
    return false;
}
void KM_match(){
    memset(match,255,sizeof(match));
    for(int i = 1; i <= n; i++) LX[i] = *max_element(G[i]+1,G[i]+1+n);
    memset(LY,0,sizeof(LY));
    for(int i = 1; i <= n; i++){
        memset(slack,INF,sizeof(slack));
        while(true){
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            if(dfs(i)) break;
            int d = INF;
            for(int j = 1; j <= n; j++) if(!visy[j]) d = min(d,slack[j]);
            for(int j = 1; j <= n; j++) if(visx[j]) LX[j]-=d;
            for(int j = 1; j <= n ;j++) if(visy[j]) LY[j]+=d;
            else slack[j]-=d;
        }
    }
    for(int i = 1; i <= n; i++) printf("%d ",match[i]);
}
int main(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++){
        scanf("%d",&G[i][j]);
        G[i][j] = log(G[i][j])*1000000;
    }
    KM_match();
    puts("");
    return 0;
}

\(H.Hour\ for\ a\ Run\)

签到

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
int n,m;
int main(){
    ____();
    cin >> n >> m;
    for(int i = 1; i < 10; i++) cout << int(ceil((n*m*i)/10.0)) << ' '; cout << endl;
    return 0;
}

\(I.Interplanetary\)

\(J.Jar\ of\ Water\ Game\)

\(K.Keep\ Calm\ and\ Sell\ Balloons\)

\(L.Less\ Coin\ Tosses\)

答案就是\(C(n,0)%2+C(n,1)%2+...+C(n,n-1)%2+C(n,n-1)%2\)
根据卢卡斯定理,答案就是2的\(N\)二进制位中1的个数次幂

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
int_fast64_t n;
#define lowbit(x) ((x)&(-x))
int main(){
    scanf("%I64d",&n);
    int_fast64_t res = 1;
    while(n) res <<= 1,n-=lowbit(n);
    printf("%I64d\n",res);
    return 0;
}

\(M.Maratona\ Brasileira\ de\ Popcorn\)

二分答案判定即可

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
using LL = int_fast64_t;
int n,c,t,A[MAXN];
bool check(int mid){
    int cur = 0, tot = 1;
    for(int i = 1; i <= n; i++){
        if(mid*1ll*t<A[i]) return false;
        if(mid*1ll*t>=cur+A[i]) cur+=A[i];
        else{
            tot++;
            cur = A[i];
        }
    }
    return tot<=c;
}
int solve(){
    int l = 1, r = 1e9+7;
    while(l<=r){
        int mid = (l+r) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    return l;
}
int main(){
    scanf("%d %d %d",&n,&c,&t);
    for(int i = 1; i <= n; i++) scanf("%d",&A[i]);
    printf("%d\n",solve());
    return 0;
}

原文地址:https://www.cnblogs.com/kikokiko/p/12236510.html

时间: 2024-08-01 11:17:57

2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)的相关文章

2018-2019 ACM-ICPC Brazil Subregional Programming Contest PART (10/13)

\[2018-2019 ACM-ICPC Brazil Subregional Programming Contest\] \(A.Slackline\ Adventure\) \(B.Marbles\) NIM游戏,把其中任意一个石子移动到(0,0)算赢,所以必败态为全部石子都到(1,2)和(2,1)这两个点而不是(0,0)了,跑出sg函数异或即可,注意如果出现先手直接赢的需要特判 //#pragma comment(linker, "/STACK:1024000000,1024000000&

(寒假GYM开黑)2018-2019 ACM-ICPC Brazil Subregional Programming Contest

layout: post title: 2018-2019 ACM-ICPC Brazil Subregional Programming Contest author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! 许老师! B.Marbles (nim博弈) 题意 一个棋盘n个点,每次可以把一个棋子移动到(x-d,y) or (x,y-d) or (x-d,y-d) 把其中一个棋子移动到(0

gym101908 [2018-2019 ACM-ICPC Brazil Subregional Programming Contest] 题解

感觉难度和邀请赛类似,题目质量也低于国内邀请赛,(题面/数据不出锅的情况下) https://codeforces.com/gym/101908 A.大概是莫比乌斯之类的,不会 B:博弈,不会 C:欧拉公式+二维偏序 首先,根据平面图欧拉公式,可推导出答案为$n+m+1+$交叉的数量 交叉的数量由三部分构成,横竖交叉数,横横交叉数和竖竖交叉数 显然,前者为$nm$,后两个为简单的二维偏序问题, 比较扯淡的是,先T了一发,从map改完二分,交的时候才意识到是没关同步 #include<bits/s

2018-2019 ACM-ICPC Brazil Subregional Programming Contest

A:留坑 B:二维sg函数,特判边界情况 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protect

Gym.101908 Brazil Subregional Programming Contest(寒假自训第六场)

这几天失眠时间都不太够,室友太会折腾了,感觉有点累,所以昨天的题解也没写,看晚上能不能补起来. B . Marbles 题意:给定N组数(xi,yi),玩家轮流操作,每次玩家可以选择其中一组对其操作,可以把它减去一个数,或同时减去一个数,当玩家操作后出现了(0,0)则胜利. 思路:注意这里是出现(0,0)胜,而不是全都是(0,0)胜,所以我们不能简单的球sg,最后异或得到答案. 但是我们转化一下,如果玩家面对的全是(1,2) 或(2,1),则他胜利,那么我们可以以这两个状态为起点得到sg函数,就

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Krak&#243;w

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik's RectangleProblem B: What does the fox say?Problem C: Magical GCDProblem D: SubwayProblem E: EscapeProblem F: DraughtsProblem G: History courseProblem H: C

2020.3.21 Benelux Algorithm Programming Contest 2019 解题报告

B-Breaking Branches 大意就是两个人掰树枝子玩,是个典型的博弈题,判断能不能被2整除就可以了 #include<cstdio> using namespace std; int main(){ long long int n,m,t; scanf("%lld",&n); if(n%2==0){ printf("Alice\n"); printf("1\n"); }else{ printf("Bob\

Fire-Fighting Hero (The 2019 Asia Nanchang First Round Online Programming Contest)

This is an era of team success, but also an era of heroes. Throughout the ages, there have been numerous examples of using the few to defeat the many. There are VV(Numbers 11 to VV) fire-fighting points in ACM city. These fire-fighting points have EE

The 2019 Aisa Nanchang First Round Online Programming Contest ——H

思路:矩阵快速幂+map 代码: #include<cmath> #include<algorithm> #include<cstdio> #include<map> const int INF=0x3f3f3f3f; const int maxn = 1e7+10; const int mod=998244353; using namespace std; typedef long long ll; map<ll,ll> mp; ll n; s