zoukankan      html  css  js  c++  java
  • Codeforces Round #611 (Div. 3)

    F

    题意:给你n-1边,n个灯,每个边连着两颗灯,有主,次灯区别,电流由主到次,每条边有一个特性,取消这条边后n个灯不能亮的值(每个灯亮值为2^i,灯编号i),由特性值由大到小给出每条边的主灯,求出每对主灯次灯。

    题解:可知是一棵树,排第一个的肯定是原点,即根。然后没出现的肯定是叶子节点,我们遍历一遍求出叶子节点,然后我们知道灯亮与编号有关,所以我们由将叶子节点放入优先队列,叶子节点从小到大与主灯从小到大匹配,当主灯中的cnt【i】为0,说明他已经没有子树,也就是他也是一颗“叶子节点了”

    就放入优先队列中继续匹配。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    priority_queue<int,vector<int>,greater<int> >pq;
    int k,n,x[maxn],vis[maxn],cnt[maxn];
    vector<pair<int,int> >G;
    int main()
    {
        cin>>n;
        int tot=n-1;
        for(int i=1;i<n;i++){
            cin>>x[i];
            vis[x[i]]=1;
            cnt[x[i]]++;
        }
        printf("%d
    ",x[1]);
        for(int i=1;i<=n;i++){
            if(!vis[i]) pq.push(i);
        }
        while(1){
            if(tot==0) break;
            int now=pq.top();pq.pop();
            int res=x[tot];tot--;
            G.push_back(make_pair(res,now));
            cnt[res]--;
            if(cnt[res]==0) pq.push(res);
        }
        int sz=G.size();
        for(int i=0;i<sz;i++){
            printf("%d %d
    ",G[i].first,G[i].second);
        }
    }
    

      

    E

    题意:每个人可以出现三个操作,将自己呆在原地,或向右移动一距离或向左。

    求最大占用地方块数和最小的占用地方块数。

    分析:最多就是尽可能得让所有房子都有人嘛,最少就是尽可能得集中这些人。
    
    代码:
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+7;
    int x[maxn],n,xx,xxx[maxn];
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> xx, x[xx]++, xxx[xx]++;
        for (int i = n + 1; i >= 1; i--) {
            if (x[i] > 1) {
                x[i - 1]++;
                x[i]--;
            }
        }
        for (int i = 0; i <= n; i++) {
            if (x[i] > 1) {
                x[i + 1]++;
                x[i]--;
            }
        }
        int most = 0;
        for (int i = 0; i <= n + 1; i++) {
            if (x[i]) most++;
        }
        int least = 0;
        for (int i = 1; i <= n + 1;) {
            if (xxx[i]) {
                i += 3;
                least++;
            } else {
                i++;
            }
        }
        cout << least << " " << most << endl;
        return 0;
    }
    

    D.Christmas Trees

    题目大意:给定n个不同的整数点,让你找m个不同的整数点,使得这m个点到到这n个点最小距离之和最小。

    分析:对于每个点,肯定是先选取距离为1的,然后再选取距离为2的,以此类推。但是有的点不一定选得到,因此我们可以用队列来存储那些可以到达的点,这样就可以得知这个题跑个bfs可行。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    int n,m,a[maxn];
    vector<int>G;
    ll ans;
    map<int,bool>vis;
    struct node
    {
        int pos,len;
    };
    queue<node>q;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            vis[a[i]]=1;
        }
        for(int i=1;i<=n;i++){
            if(vis[a[i]-1]==0) q.push(node{a[i]-1,1}),vis[a[i]-1]=1;
            if(vis[a[i]+1]==0) q.push(node{a[i]+1,1}),vis[a[i]+1]=1;
        }
        while(m--){
            node res=q.front();q.pop();
            int u=res.pos,v=res.len;
            G.push_back(u);
            ans+=v;
            if(vis[u-1]==0){
                q.push(node{u-1,v+1});
                vis[u-1]=1;
            }
            if(vis[u+1]==0){
                q.push(node{u+1,v+1});
                vis[u+1]=1;
            }
        }
        printf("%lld
    ",ans);
        int sz=G.size();
        for(int i=0;i<sz;i++){
            if(i)printf(" %d",G[i]);
            else printf("%d",G[i]);
        }
        puts("");
        return 0;
    }
    

    题目大意:每个人都要给其他一个人一个礼物,并且每个人都要收到一个礼物。请你构造一种合法的赠送礼物的方法,使得每个人都赠送非自己的人一个礼物,并且从其他人那里收到一个礼物。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef vector<int> VI;
    typedef vector<VI> VII;
    typedef vector<VII> VIII;
    typedef pair<int, int> PII;
    
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define per(i,a,b) for(int i=(a);i>=(b);i--)
    
    const int N = 2e5 + 5;
    const ll MOD = 1e9 + 7;
    
    int flag[N];
    int give[N];
    int gett[N];
    queue<int> Q;
    
    int num = 0;
    
    int main()
    {
        int n;
        scanf("%d", &n);
        rep(i,1,n)
        {
            int x;
            scanf("%d", &x);
            flag[i] = x;
            give[i] = x;
            if(x != 0)
                gett[x] = i;
            else
                num ++;
        }
        rep(i,1,n)
        {
            if(gett[i] == 0)
                Q.push(i);
        }
        int pos = 1;
        rep(i,1,n)
        {
            if(give[i] == 0)
            {
                pos = i;
                while(give[pos] == 0)
                {
                    give[pos] = Q.front();
                    Q.pop();
                    if(pos == give[pos])
                    {
                        Q.push(pos);
                        give[pos] = Q.front();
                        Q.pop();
                    }
                    pos = give[pos];
                    num --;
                }
            }
        }
        rep(i,1,n)
        {
            if(give[i] == i)
            {
                rep(j,1,n)
                {
                    if(flag[j] == 0)
                    {
                        swap(give[i], give[j]);
                        break;
                    }
                }
            }
        }
        rep(i,1,n)
        {
            printf("%d ", give[i]);
        }
        printf("
    ");
        return 0;
    }
    

      

  • 相关阅读:
    数据库——表操作(5)
    数据库——存储引擎(4)
    数据库——库操作(3)
    数据库——初始mysql语句(2)
    数据库——初识数据库(1)
    并发编程——协程(5)
    并发编程——IO模型(6)
    并发编程——多线程(4)
    并发编程——多进程——multiprocessing开启进程的方式及其属性(3)
    并发编程——多进程——理论(2)
  • 原文地址:https://www.cnblogs.com/hgangang/p/12237328.html
Copyright © 2011-2022 走看看