• “蔚来杯“2022牛客暑期多校训练营(加赛) K.Killer Sajin‘s Matrix


    原题链接

    传送门

    题目大意

    给定 n , m , k n,m,k n,m,k,求大小为 n × m n \times m n×m 01 01 01 矩阵 a a a ,满足

    • 每行每列总和为奇数;
    • 恰好有 k k k 1 1 1 n m − k nm-k nmk 0 0 0

    题解

    这是一道构造题,考虑每行每列总和为奇数,所以每行每列所对应的 1 1 1 的个数必然大于等于 1 1 1 ,贪心的思想,我们先考虑在坐标 ( i , i ) (i,i) (i,i) 上放上 1 1 1 ,贪心的使得每一行列的初始值均为 1 1 1 ,然后再将剩下的均匀两个两个分配给每一行/列。
    考虑,每一行的值 h i h_i hi 所对应的列值 w i w_i wi
    显然的,对于当前的 w i w_i wi ,我们需要找到一个已填个数最大的值去对应,用优先队列维护即可,
    同样的,对于列中数字的选择,我们也要从大到小来枚举。
    特例:

    • n , m n,m n,m 都为奇数且 k = n m − 2 k=nm-2 k=nm2 时,我们发现,对于一个全是 1 1 1 的矩阵,无法满足删去一个数后使得行列同时减一来满足条件;
    • k < m a x ( n , m ) k k<max(n,m) 时,显然无法使得每行每列至少有一个数字;
    • n , m , k n,m,k n,m,k 的奇偶性中有两个不同时,我们发现无法使得为奇数;

    特判即可。
    计算完我们可以发现,将剩余的值平均分配给每一行/列构造的序列是最优解,因为 2 x + 1 , 2 x − 1 2x+1,2x-1 2x+1,2x1 的情况中包含着 2 x + 3 , 2 x − 3 2x+3,2x-3 2x+3,2x3 , 若当前不满足,则其他构造方法必然不满足。

    参考代码

    #include
    #define ll long long
    using namespace std;
    const int N=1e5+5;
    int n,m,k,T;
    int h[N],w[N];
    int main()
    {
        cin>>T;
        while(T--)
        {
            int b=0;
            scanf("%d%d%d",&n,&m,&k);
            if(n&1 && m&1 && n*m-2==k || ((n&1)+(m&1)+(k&1))%3!=0 || k<max(n,m))    //特判
            {
                puts("No");
                continue;
            }
            int t=k-n,tot=1;
            for(int i=1;i<=n;i++)
                h[i]=1;
            for(int i=1;i<=m;i++)
                w[i]=1;
            while(t)                    //构造一段序列使得其为2x+1,2x+1...2x-1,2x-1使得尽可能平均
            {
                h[tot]+=2;
                t-=2;
                tot%=n;
                tot++;
            }
            t=k-m,tot=1;
            while(t)
            {
                w[tot]+=2;
                t-=2;
                tot%=m;
                tot++;
            }
            priority_queue<pair<int,int> > q;               //用优先队列维护最大值
            queue<pair<int,int> > q1;
            vector<pair<int,int> > ans;
            for(int i=1;i<=n;i++)
                q.push(make_pair(h[i],i));
            for(int i=1;i<=m;i++)
            {
                while(w[i])              //从大到小枚举列值
                {
                    w[i]--;
                    if(q.empty())
                    {
                        b=1;
                        break;
                    }
                    pair<int,int> now=q.top();            //行值
                    q.pop();
                    ans.push_back(make_pair(now.second,i));
                    now.first--;
                    if(now.first)
                        q1.push(now);
                }
                if(b)
                    break;
                while(q1.size())
                {
                    q.push(q1.front());
                    q1.pop();
                }
            }
            if(b)
            {
                puts("No");
                continue;
            }
            puts("Yes");
            for(int i=0;i<ans.size();i++)
                cout<<ans[i].first<<" "<<ans[i].second<<endl;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
  • 相关阅读:
    TRex学习之旅九
    OpenAI CEO被董事会开除:内情如何
    麒麟 Kylin V10 一键安装 Oracle 11GR2 单机 ASM(231017)
    2023年09月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试
    (论文阅读32/100)Flowing convnets for human pose estimation in videos
    Springboot如何实现数据预热
    第二十八章 管理许可(一)
    公共4G广播音柱有哪些用处
    教你这4步去判断网络故障点
    【LeetCode】双指针题解汇总
  • 原文地址:https://blog.csdn.net/PTCCTP/article/details/126403774