E. Obtain a Permutation

给定一个n×m矩阵,目标是将其还原到特定排列。有两种操作:单点数值修改和整列上移。问题求解最小操作次数。通过分析发现操作互相独立,对于每列,最优操作次数是min(0≤i 摘要由CSDN通过智能技术生成

题意:
给一个 n×m 的矩阵,你想要把它还原成如下的矩阵
在这里插入图片描述
你有两种操作:
• 选择一个数,修改它的值。
• 选择一列,每个元素上移一位,第一行的元素移到第 n 行。
求还原的最小操作次数。

数据范围:
1≤n,m≤2⋅10^5
1≤n⋅m≤2⋅10^5

思路:
对于任意一行,我们可以发现,无论是先进行单点修改,后进行整列上移,还是先进行整列上移,后进行单点修改。都是没有影响的,两种操作是互相独立的。所以我们可以设定samej,i表示第j列上移i个单位后,有多少个数是不需要改变的,这时我们可以得到对于任意一列,操作次数是n-samej,i+i,因为n-samej,i是需要改变的操作次数,i是上移的次数,所以对于任意一列,最优答案就为min(0≤i<n)(n-samej,i+i)。所以最终整体答案为所有列最优答案的求和。这时我们就只需要求出same即可,在判断ai,j是否属于第j列的数字时,有三个条件:j≤ai,j , ai,j≤m*n , (ai,j-j) % m = 0.满足这三个条件,就可以说明ai,j是第j列的数字。然后我们还需要判断ai,j应该在第几行,我们设ai,j应该在第k行。通过还原后的矩阵得到公式k=(ai,j-j)/m+1。最后判断当前列和第k列的位置,如果k≤i,就same[i-k]++,如果k>i,就same[i-k+n]++.最后通过最上面的公式求得答案即可。

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const int maxn=2e5
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值