zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)

    D.Distinctive Character

    看到样例,第一个反应贪心。先写了个按这一位1和0的数目多少,确定0还是1的东西。感觉不够真,又写了个尽量加到相似的比较小的串上的贪心。在和前边的那个组合一下,换了换顺序。。。好吧就过了13组样例。。。正解如下:考虑如何求出,所有2^k个状态与这n个串的最大相似度。起初的n个串的答案显然为k,那改变一个位置,相似度就改变为k-1,对于一个状态,越早算出来的相似度,越大,那么就可以直接bfs求出所有状态的最大相似度了。答案就是取最小值的状态。

    #include <bits/stdc++.h>
    #define mem(W) memset(W,0,sizeof(W))
    using namespace std;
    int n, k, a[1<<23], b[1<<23];
    char s[25];
    int q[1<<23],l=0,r=0;
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=0;i<(1<<k);++i)b[i]=-1;
        for(int i=1;i<=n;++i) {
            scanf(" %s",s);
            for(int j=0;j<k;++j) a[i]=a[i]*2+(s[j]-'0');
            q[r]=a[i];++r;
            b[a[i]]=k;
        }
        while(l<r){
            int S=q[l]; ++l;
            for(int i=0;i<k;++i){
                if(b[S^(1<<i)]==-1){
                    b[S^(1<<i)]=b[S]-1;
                    q[r]=S^(1<<i); ++r;
                }
            }
        }
        int MN=10000,ans=0;
        for(int i=0;i<(1<<k);++i){
            if(MN>b[i]){
                MN=b[i];
                ans=i;
            }
        }
        for(int i=k-1;i>=0;--i)printf("%d",!!(ans&(1<<i)));puts("");
    }
    

    E.Emptying the Baltic 

    bfs暴搜的做法很显然,一直搜到所有位置都无法流向周围的格子为止,但是会tle。考虑剪枝:1)水位低的地方,不能流向高的地方;2)没有水也不能流了;3)最重要的一个剪枝/贪心,我们尽量先去从当前水位比较高的地方搜,用优先队列可以解决。(读题能力好差。。。

    #include <cstdio>
    #include <queue>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 550;
    inline int read() {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    int dx[]={0, 0, 1, 1, -1, -1, 1, -1};
    int dy[]={1,-1, 0,-1, 0,   1, 1, -1};
    int n, m, xs, ys;
    ll mp[N][N], h[N][N];
    struct node{
        int x,y;
        bool operator < (const node a) const {
            return h[a.x][a.y] < h[x][y];
        }
        node(){}node(int a,int b){x=a;y=b;}
    };
    inline int inb(int x,int y) {
        if(x>n||x<1||y>m||y<1)return 0;
        return 1;
    }
    inline ll solve(node e,node s){
        ll t;
        if(mp[s.x][s.y] >= h[e.x][e.y]) {
            t=h[s.x][s.y]-mp[s.x][s.y];
            h[s.x][s.y]-=t;
            return t;
        }
        else {
            t=h[s.x][s.y]-h[e.x][e.y];
            h[s.x][s.y]-=t;
            return t;
        }
        return t;
    }
    
    inline ll bfs(int sx, int sy) {
        ll ans=0;
        priority_queue<node> q;
        q.push(node(sx,sy));
        ans += (-mp[sx][sy]);
        h[sx][sy]=mp[sx][sy];
        while(!q.empty()) {
            node u=q.top();q.pop();
            rep(i,0,7) {
                int tx=u.x+dx[i], ty=u.y+dy[i];
                if(!inb(tx,ty)||mp[tx][ty]>=0||h[tx][ty] <= h[u.x][u.y])continue;
                if(h[tx][ty]==mp[tx][ty]) continue;
                ll tmp=solve(u,node(tx,ty));
                ans+=tmp;
                q.push(node(tx,ty));
            }
        }
        return ans;
    }
    int main() {
        n=read(),m=read();
        rep(i,1,n)rep(j,1,m)mp[i][j]=read();
        xs=read(),ys=read();
        printf("%lld
    ", bfs(xs,ys));
    }
    

    G. Galactic Collegiate Programming Contest

    用数据结构维护比1队排名靠前的队伍。一眼考虑用优先队列加数组标记,感觉删除的复杂度就没有保证,状态本身就多,还额外加了一些,肯定会T,就没写。然后,考虑用set删除操作就很方便,然而还是T了。(于是膜了题解。。。还学了很多神奇的操作%%%)用multiset的话,有很多重复的值,时间就更优秀了。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    const int N = 1e5 + 100;
    typedef long long ll;
    using namespace std;
    struct node{
        int x,y;
        node(){}node(int a,int b){x=a;y=b;}
        bool operator < (const node a)const {
            if(a.y!=y) return y > a.y;
            return x < a.x;
        }
    };
    multiset<node> s;
    int n,m,t,p,a[N],b[N];
    int main() {
        scanf("%d%d",&n,&m);
        rep(i,1,m) {
            scanf("%d%d",&t,&p);
            if(t!=1) {
                if(node(a[t],b[t]) < node(a[1],b[1])) s.erase(s.find(node(a[t],b[t])));
                a[t]+=p;++b[t];
                s.insert(node(a[t],b[t]));
            }
            else {
                a[t]+=p;++b[t];
            }
            while(!s.empty()&&!(*--s.end()<node(a[1],b[1]))) s.erase(--s.end());
            printf("%d
    ",s.size()+1);
        }
    }
    
  • 相关阅读:
    现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1。 buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“ ”分割
    面向对象程序设计中类与类的关系都有哪几种?分别用类图实例说明。
    Java为什么没有指针
    touchz,mkdir,vi的区别
    session使用方法
    迪杰斯特拉算法-文档读取数据
    数据结构---公交线路提示系统(Java后台+excel表格+web前端)
    caffe中train过程的train数据集、val数据集、test时候的test数据集区别
    caffe程序中出现的db.cpp:#line(行号) unknown database backend问题
    caffe的cancat层
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9086143.html
Copyright © 2011-2022 走看看