zoukankan      html  css  js  c++  java
  • CodeForces 1521E Nastia and a Beautiful Matrix 题解

    CF1521E链接

    这道题有多解,下面给出一种无需二分的做法。

    Hint 1 先假设已经求出了 $size$。

    观察题目所给条件,是否可以把网格分成两部分,使得每部分里互不影响,只需要考虑两部分之间的冲突?

    Hint 2 按行的奇偶性来分,那么网格应当是这样的:
    11111
    2 2 2
    11111
    2 2 2
    11111
    

    怎样安排数字,才能最大化利用上面Hint 1的性质?

    Hint 3 存在一种安排方法,使得只有一种数字 $x$ 可能出现冲突。在放置 $x$ 时,会出现什么问题?如何避免?
    题解 假设 $size$ 为最小边长。

    考虑到 (mat_{i,j} eq mat_{i+1,j+1})(mat_{i,j+1} eq mat_{i+1,j})

    我们将网格按行的奇偶性分成两部分 (S_1), (S_2)

    11111
    2 2 2
    11111
    2 2 2
    11111
    

    发现,每部分里的数字两两不影响,只有两部分间才可能出现冲突。

    然后,我们如果把所有相同的数字放在一起,按某种顺序排好,先填 (S_1), 再填 (S_2),可以做到,只有1种数字 (x) 同时在 (S_1)(S_2) 中出现。理解一下,因为数字是一段一段的,肯定只有一段从中间被分开了。

    顺便算出 (x) 留在 (S_1) 中的个数 (num) (则在 (S_2) 中的有 (cnt_{x} - num) 个)。

    为了不冲突,把(S_1) 里的放在下图 (A) 处,把(S_2)里的放在 (B) 处。

    A A A
    B B B
    A A A
    B B B
    A A A
    

    这会带来新的问题:(S_1) 里最多只能放 (lim = (leftlceildfrac{size}{2} ight ceil)^2) 个,可能不够放。为了避免,我用的方法是:把 (a_i) 排序,按 (a_i) 的降序填数。

    简单证明一下,设 (n geq 2)(cap = size imes leftlceildfrac{size}{2} ight ceil)(S_1) 的大小,则(a_1 geq a_2 geq ... geq a_n)。显然,(a_1) 对应的数字不会成为 (x)

    假设 (x)(a_k) 所对应的,则 (sum1 = a_1 + a_2 + ... + a_{k-1} leq cap)(sum2 = a_1 + a_2 + ... + a_k > cap)。因此 (a_k leq dfrac{cap}{k})。而 (num < a_k)

    (k = 2) 时,(num) 最大值可达 (dfrac{cap}{2}),显然 (lim geq dfrac{cap}{2}) 。可见 (lim) 恒不小于 (num)

    剩下的数字呢?(x) 前面的都放 (S_1),后面的都放 (S_2)

    (size) 的方法还没说呢。上述构造方法可以保证,满足下面两个条件的输入都能找到解。

    1.(m leq size^2 - (leftlfloordfrac{size}{2} ight floor)^2)

    2.(max{a_i} leq cap)

    枚举即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mit map<int,int>::iterator
    #define sit set<int>::iterator
    #define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
    #define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
    #define ltype int
    #define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
    #define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
    #define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mpr make_pair
    #define pb push_back
    #define fastio ios::sync_with_stdio(false)
    #define check(x) if(x>=mod) x-=mod
    const int inf=0x3f3f3f3f,mod=1000000007;
    const double pi=3.1415926535897932,eps=1e-6;
    void chmax(int &x,int y){if(x < y) x = y;}
    void chmin(int &x,int y){if(x > y) x = y;}
    int qpow(int x,int y){
        int ret = 1;
        while(y) {
            if(y & 1) ret = (ll)ret * x % mod;
            x = (ll)x * x % mod;
            y >>= 1;
        }
        return ret;
    }
    int n,m,mx,ans[1005][1005];pii a[100005];
    void solve()
    {
        scanf("%d%d",&m,&n);
        rep(i,1,n) scanf("%d",&a[i].fi),a[i].se = i;
        sort(a+1,a+n+1);reverse(a+1,a+n+1);
        mx = 1;rep(i,2,n) if(a[mx] < a[i]) mx = i;
        int s = 0;while(s * ((s + 1) / 2) < a[mx].fi || (s * s) - ((s / 2) * (s / 2)) < m) s++;
        int cap = s * ((s + 1) / 2);
        int id = n + 1, rest = 0;rep(i,1,n) if(rest + a[i].fi > cap) {id = i;break;} else rest += a[i].fi;
    
        int u = 1, v = 1;
        int num = cap - rest;
        if(id <= n)rep(i,1,num) {
            ans[u][v] = a[id].se;
            v += 2;
            if(v > s) v = 1, u += 2;
        }
        u = 1;v = 1;
        rap(i,1,id) {
            while(a[i].fi){
                if(!ans[u][v]) ans[u][v] = a[i].se, a[i].fi--;
                v++;
                if(v > s) v = 1, u += 2;
            }
        }
        
        u = 2;v = 1;
        if(id <= n) rep(i,1,a[id].fi - num) {
            ans[u][v] = a[id].se;
            v += 2;
            if(v > s) v = 1, u += 2;
        }
        rep(i,id+1,n) {
            while(a[i].fi){
                if(!ans[u][v]) ans[u][v] = a[i].se, a[i].fi--;
                v += 2;
                if(v > s) v = 1, u += 2;
            }
        }
        printf("%d
    ",s);
        rep(i,1,s) rep(j,1,s) printf("%d%c",ans[i][j],j==s?'
    ':' '),ans[i][j] = 0;
    }
    int main()
    {
        int T;scanf("%d",&T);while(T--) solve();return 0;
    }
    
  • 相关阅读:
    VysorPro助手
    Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
    Play 2D games on Nexus 6P running Android N7.1.1 with Daydream View VR headset
    Native SBS for Android
    ADB和Fastboot最新版的谷歌官方下载链接
    How do I install Daydream on my phone?
    Daydream Controller手柄数据的解析
    蓝牙BLE传输性能及延迟分析
    VR(虚拟现实)开发资源汇总
    Android(Java)控制GPIO的方法及耗时分析
  • 原文地址:https://www.cnblogs.com/yz-beacon-cwk/p/14747377.html
Copyright © 2011-2022 走看看