zoukankan      html  css  js  c++  java
  • qbxt 10 月模拟赛 Day1

    感觉是普及组模拟赛。。

    A

    手玩,发现 (n =2) 很特殊:因为谁先手谁就能赢。

    读入这么大,肯定之和数的性质有关,由于这是 NOIP 模拟赛,猜一发奇偶性。

    (n) 为偶数时:黑妞必胜。(等价于有最大的牌的人必胜)

    黑妞后手时:先手出 (i) 他跟 (i+1),一直到对手只剩一张牌的时候出最大的牌,然后就可以跑了。(即使中间用了最大的牌也没关系:因为这样等价于化为了 (n-2) 的子问题)

    黑妞先手时:自己先出个最小的,然后按照上述策略即可。在自己剩下两张牌的时候突然打大牌。

    (n) 为奇数时:先手必胜

    先手为皮蛋时:第一次出 (1),转化为了 (n) 为偶数并且皮蛋有最大牌的必胜局面。

    先手为黑妞时:总有策略让皮蛋的 (1) 一直留在手里,皮蛋出最大牌之后会转化为 (n) 为偶数的有最大牌的局面。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 1e5 + 5;
    char str[MAXN];
    
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%s",str+1);int len = strlen(str+1);
            int o;scanf("%d",&o);
            int x = str[len]-'0';
            printf("%d
    ",o|((!(len==1&&x<=3))&(!(x&1))));
        }
        return 0;
    }
    
    

    B

    染色问题。倒序处理,假设当前染行,只需要知道有多少列被染了就行。

    模拟即可。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    inline char nc(){
        #define SIZE 1000000+3
        static char buf[SIZE],*p1 = buf+SIZE,*p2 = buf+SIZE;
        if(p1 == p2){
            p1 = buf;p2 = buf+fread(buf,1,SIZE,stdin);
            if(p1 == p2) return -1;
        }
        return *p1++;
        #undef SIZE
    }
    
    template <typename T>
    inline void read(T &x){
        x = 0;int flag = 0;char ch = nc();
        while(!isdigit(ch)){
            if(ch == '-') flag = 1;
            ch = nc();
        }
        while(isdigit(ch)){
            x = (x<<1) + (x<<3) + (ch^'0');
            ch = nc();
        }
        if(flag) x = -x;
    }
    
    const int MAXN = 1e6 + 5;
    int n,m,k;
    int x[MAXN],y[MAXN],z[MAXN];
    bool vis[2][MAXN];
    
    int main(){
        read(n);read(m);read(k);
        FOR(i,1,k) read(x[i]),read(y[i]),read(z[i]);
        int row=0,col=0;LL ans = 0;
        ROF(i,k,1){
            if(vis[x[i]][y[i]]) continue;
            vis[x[i]][y[i]] = 1;
            if(x[i] == 0) ans += z[i]*std::max(0,m-col),++row;
            else ans += z[i]*std::max(0,n-row),++col;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    

    C

    暴力直接 nth_element

    一个靠谱的做法是求出所有交点,只有在交点才会变换排名。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 7000+5;
    int n,q;
    int now;
    
    struct Node{
        int k,b,id;
        Node(int k=0,int b=0,int id=0) : k(k),b(b),id(id) {}
    }a[MAXN];
    
    inline bool cmp(const Node &a,const Node &b){
        LL ay = 1ll*a.k*now+a.b,by = 1ll*b.k*now+b.b;
        return ay==by ? a.id < b.id : ay > by;
    }
    
    int main(){
        scanf("%d",&n);
        FOR(i,1,n) scanf("%d%d",&a[i].k,&a[i].b),a[i].id = i;
        scanf("%d",&q);
        FOR(i,1,q){
            int x;scanf("%d%d",&now,&x);
            std::nth_element(a+1,a+x,a+n+1,cmp);
            printf("%d
    ",a[x].id);
        }
        return 0;
    }
    
    
    

    D

    可以证明每次划分的一定至少有一个部分大小为 (1)(这样 (1) 减的尽量多)

    (f_{i,j}) 表示分别还剩 (i,j) 个的答案,(O(n^3))

    写出转移式子,是个前缀 (min) 的形式,树状数组维护即可。

    #include <bits/stdc++.h>
    
    #define fi first
    #define se second
    #define db double
    #define U unsigned
    #define P std::pair<int,int>
    #define LL long long
    #define pb push_back
    #define MP std::make_pair
    #define all(x) x.begin(),x.end()
    #define CLR(i,a) memset(i,a,sizeof(i))
    #define FOR(i,a,b) for(int i = a;i <= b;++i)
    #define ROF(i,a,b) for(int i = a;i >= b;--i)
    #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
    
    const int MAXN = 2000+5;
    LL f[MAXN][MAXN],sma[MAXN],smb[MAXN];
    int n,m,a[MAXN],b[MAXN];
    
    inline void upmin(LL &x,LL y){
        if(x > y) x = y;
    }
    
    struct BIT{
        #define lowbit(x) ((x)&(-(x)))
        LL tree[MAXN];
    
        inline void add(int pos,LL x){
            ++pos;
            while(pos < MAXN){
                tree[pos] = std::min(tree[pos],x);
                pos += lowbit(pos);
            }
        }
    
        inline LL qry(int pos){
            LL res = 1e18;++pos;
            while(pos){
                res = std::min(res,tree[pos]);
                pos -= lowbit(pos);
            }
            return res;
        }
    }mn1[MAXN],mn2[MAXN];
    
    int main(){
        freopen("D.in","r",stdin);
        freopen("D.out","w",stdout);
        scanf("%d%d",&n,&m);
        FOR(i,1,n) scanf("%d",a+i),sma[i] = sma[i-1]+a[i];
        FOR(i,1,m) scanf("%d",b+i),smb[i] = smb[i-1]+b[i];
        FOR(i,1,m) smb[i] -= i;
        FOR(i,1,n) sma[i] -= i;
        FOR(i,1,n) a[i]--;FOR(i,1,m) b[i]--;
        CLR(f,0x3f);f[0][0] = 0;
        CLR(mn1,0x3f);CLR(mn2,0x3f);
        mn1[0].add(0,f[0][0]+sma[0]*b[1]);
        mn2[0].add(0,f[0][0]+smb[0]*a[1]);
        FOR(i,1,n){
            FOR(j,1,m){
                upmin(f[i][j],mn1[j-1].qry(i-1)+sma[i]*b[j]);
                upmin(f[i][j],mn2[i-1].qry(j-1)+smb[j]*a[i]);
                mn1[j].add(i,f[i][j]-sma[i]*b[j+1]);
                mn2[i].add(j,f[i][j]-smb[j]*a[i+1]);
            }
        }
        printf("%lld
    ",f[n][m]);
        return 0;
    }
    
  • 相关阅读:
    jquery拖拽插件 tableDnD
    爱回收jd图标
    struts2框架学习笔记2:配置详解
    struts2框架学习笔记1:搭建测试
    hibernate框架学习笔记12:查询优化
    hibernate框架学习笔记11:Criteria查询详解
    hibernate框架学习笔记10:HQL查询详解
    hibernate框架学习笔记9:多对多关系案例
    hibernate框架学习笔记8:一对多关系案例
    hibernate框架学习笔记7:HQL查询、Criteria查询简介
  • 原文地址:https://www.cnblogs.com/rainair/p/14305849.html
Copyright © 2011-2022 走看看