ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

cf1521 E. Nastia and a Beautiful Matrix

2022-07-20 00:03:49  阅读:127  来源: 互联网

标签:Beautiful cf1521 int big Nastia 位置 网格 黄格 sum


题意:

你有 \(a_i\) 个数字 \(i\),要把它们都放进 \(n*n\) 网格内,每格可以为空或者放一个数。要求对于任何 \(2*2\) 子网格,有数的位置不能超过 \(3\) 个,且对角线上的数不能相等

输出放数后的网格图,要求 \(n\) 最小

思路:

image

当 \(n\) 确定的时候要咋放?

首先横纵坐标均为偶数的位置(图中白色)不放数,这样就能满足第一个要求,且被浪费的格子数最少。为了放下所有数,就要求 \(sum \le n^2-\lfloor \frac n2 \rfloor ^2\)

那么在 \(2*2\) 网格内与白色格子对角的所有位置(图中蓝色)就能随便放

记出现次数最多的数为 \(x\),其出现次数为 \(a_x\),那么当 \(a_x\) 不超过蓝+黄格数,即 \(a_x\le n\cdot\lceil \frac n2 \rceil\) 时一定有合法方案

方案:先放出现次数最多的数 \(x\) ,再随便放其他数,放完一个再到另一个。先在黄色格放数、黄满了放蓝、蓝满了再放红。

啥时候会违背第二个要求?首先 \(x\) 顶多把黄蓝都放满,故肯定不会违背;如果某个数 \(y\neq x\) 放了一些黄格,然后放满蓝格,再放一些红格,这些黄格红格中恰有某对在对角位置的话就寄了,但注意到黄格数小于等于蓝格数,而这样一来 \(x\) 全在黄格里于是 \(x\) 的数量比黄格数少,\(y\) 比蓝格数多故比 \(x\) 还多,矛盾

//代码0难度,建议别看
const signed N = 5 + 1e5;
int sum, k, n, a[N];

void nxt(int& i, int& j) { //下一个位置
    if(j + 2 <= n) j += 2;
    else if(i + 2 <= n) i += 2, j = j % 2 ? 1 : 2;
    else if(i % 2 && !(j % 2)) i = j = 1; //黄变蓝
    else if(i % 2 && j % 2) i = 2, j = 1; //蓝变红
}

void sol() {
    cin >> sum >> k;
    for(int i = 1; i <= k; i++) cin >> a[i];

    int big = max_element(a + 1, a + 1 + k) - a;
    
    ll l = 0, r = 2e5; //二分找n
    while(l < r) {
        ll mid = l + r >> 1;
        if(sum<=mid*mid-(mid/2)*(mid/2) && a[big]<=(mid+1)/2*mid)
            r = mid;
        else l = mid + 1;
    }

    n = l; vector<vector<int>> g(n+1,vector<int>(n+1,0));
    int x = 1, y = 2; //起点
    if(n == 1) x = y = 1; //这种写法要特判
    while(a[big])
        g[x][y] = big, a[big]--, nxt(x, y);
    for(int i = 1; i <= k; i++)
        while(a[i]) g[x][y] = i, a[i]--, nxt(x, y);
    
    cout << n << endl; for(int i = 1; i <= n; i++) //输出答案
        for(int j = 1; j <= n; j++) cout << g[i][j] << "\n "[j<n];
}

标签:Beautiful,cf1521,int,big,Nastia,位置,网格,黄格,sum
来源: https://www.cnblogs.com/wushansinger/p/16496273.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有