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

Posted kikokiko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",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
",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
",solve());
    return 0;
}

以上是关于2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)的主要内容,如果未能解决你的问题,请参考以下文章

2018-2019 ACM-ICPC Brazil Subregional Programming Contest

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

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

2018-2019 ACM-ICPC Brazil Subregional Programming Contest

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

2018-2019 ACM-ICPC Brazil Subregional Programming Contest B. Marbles