首页 > 其他分享 >[题解] Codeforces 1720 E Misha and Paintings 结论

[题解] Codeforces 1720 E Misha and Paintings 结论

时间:2022-08-20 18:46:10浏览次数:64  
标签:颜色 Paintings 题解 mnr mxr Codeforces 边长 mxc define

算是诈骗题?

令一开始就存在的颜色数为cnt。k>=cnt的情况,显然每次找一个出现不止一次的颜色,然后把这个颜色的恰好一个方块替换成一种没有出现过的颜色就可以了,\(k-cnt\)次解决问题。先把这种特判掉。

然后再把k=1的情况也判掉,不然后面不好弄。

否则的话可以说明:最多需要2次操作。只要证明2次一定可以解决问题就可以了。

证明:

先找到最大的L,满足把整个网格左上角边长为L的正方形全染成\(a_{1,1}\)(下标从1开始)的颜色后,剩下的不同颜色数\(\geq k\)。如果这步操作做完后刚好有k种颜色,就直接完事了;否则,L不能继续增加是因为这个边长为L的正方形右边和下面的第一列如果也被覆盖,剩下颜色数会<k。我们第二次操作用一个右下角在\((L+1,L+1)\)的正方形,把区域内染成\(a_{1,1}\)的颜色。大小从1开始逐渐扩大,每次扩大都会使不同颜色数减少0或1或2。那么在第一次减少到\(\leq k\)时,只能是k或k-1。如果是k就完事,否则可以把这个正方形的颜色改成一种没有出现过的。如果第一次减少到\(\leq k\)时,边长已经达到\(L+1\)且是k-1,那么把第一次操作的正方形边长改成L+1,第二次再在第一次的正方形内部随便操作一次即可。

剩下就是判断是否能一次搞定了。先枚举操作的正方形的边长l,然后尝试算出每一个边长为l的正方形内部完整地覆盖了几种颜色。对于每种颜色,求出它出现的最上、最下、最左、最右的位置,则能完整覆盖这种颜色的边长为l的正方形的左上顶点在一个矩形内部,用差分做一个矩形加即可。

时间复杂度\(O(n^3)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define pb push_back
#define fi first
#define se second
#define mpr make_pair

using namespace std;

int n,k,a[510][510],mnr[250010],mxr[250010],mnc[250010],mxc[250010],sum[510][510];
map <int,int> mp;

int main()
{
  rep(i,250005) mnr[i]=mnc[i]=1e9,mxr[i]=mxc[i]=-1e9;
  cin>>n>>k;
  rep(i,n) rep(j,n)
  {
    scanf("%d",&a[i][j]),mp[a[i][j]]=1;
    mnr[a[i][j]]=min(mnr[a[i][j]],i);mxr[a[i][j]]=max(mxr[a[i][j]],i);
    mnc[a[i][j]]=min(mnc[a[i][j]],j);mxc[a[i][j]]=max(mxc[a[i][j]],j);
  }
  if(k==1)
  {
    if(mp.size()==1) puts("0");
    else puts("1");
    return 0;
  }
  if(k>=mp.size())
  {
    cout<<k-mp.size()<<endl;
    return 0;
  }
  repn(i,n-1)
  {
    rep(j,n+3) rep(p,n+3) sum[j][p]=0;
    repn(j,n*n) if(mnr[j]<1e9)
    {
      pii most=mpr(mnr[j],mnc[j]),least=mpr(mxr[j]-i+1,mxc[j]-i+1);
      least.fi=max(least.fi,0);least.se=max(least.se,0);
      if(most.fi<least.fi||most.se<least.se) continue;
      ++sum[least.fi][least.se];++sum[most.fi+1][most.se+1];
      --sum[most.fi+1][least.se];--sum[least.fi][most.se+1];
    }
    rep(j,n) rep(p,n) sum[j][p+1]+=sum[j][p];
    rep(j,n) rep(p,n) sum[j+1][p]+=sum[j][p];
    rep(j,n-i+1) rep(p,n-i+1)
    {
      int lft=mp.size()-sum[j][p];
      if(lft==k-1||lft==k)
      {
        puts("1");
        return 0;
      }
    }
  }
  puts("2");
  return 0;
}

标签:颜色,Paintings,题解,mnr,mxr,Codeforces,边长,mxc,define
From: https://www.cnblogs.com/legendstane/p/16608381.html

相关文章

  • 题解 TSP 但是你有约束
    Description给定一张带权完全图,求一条路径满足不重复经过一个点。在过点\(i\)时,\(1\cdotsi-1\)要么全访问过,要么都没有访问过。点数\(n\)有\(1\len\le1e3......
  • 题解 Trie 但是你要最小化它的节点数量
    名字瞎取的Description给定\(n\)个字符串\(s\),可以对\(s_i\)的字符打乱,将这些字符串加入一个trie里面求节点数量最小值。\(n\le16,\sum|s_i|\le10^6\)。So......
  • codeforces963D. Frequency of String【哈希】
    我的腿让我停下,可是我的心却不许我这么做今天又是为了明知多半不可能的事情奔波一早,一天里,出了很多丑,犯了很多错,见了很多人,有了很多意想不到的收获,我选择了我的生存方式......
  • Codeforces Round #815 (Div. 2) 题解
    CF1720A.BurenkaPlayswithFractions给出两个分数$\dfrac{a}{b}$和\(\dfrac{c}{d}\),你每次操作能够选择其中一个分数的分子或分母,将其乘上任意一个整数(当然不能......
  • 2022 牛客多校 Extra & 第九场部分题解
    2022牛客多校第九场&Extra部分题解前段时间沉迷生活大爆炸&原神&vtb&galgame&番无法自拔,因此咕到现在。。。Cmostp挺妙的题。本以为有一只log的做法。......
  • Codeforces 杂题集
    本文主要把近期\(CF-Div.2\)的\(A,B,C,D\)题进行做Round815A题意给你两个分数\(\frac{a}{b},\frac{c}{d}\),问你最少几次使两个分数相等。Solution首先考虑,最......
  • 题解CF94B Friends
    简洁题意:求出任三点之间是否存在直接连通或都不连通,若存在,输出WIN,否则输出FAIL由于数据范围非常小,m<=10,则我们可以采用暴力枚举三个点的方式求出答案#include<bit......
  • Codeforces Round #815 (Div. 2) D2 Xor-Subsequence (hard version)
    原题链接\(A>B\),总是有二进制下从高到低的前\(k\)位相等,第\(k+1\)位\(A\)是\(1\),\(B\)是\(0\)本题中\(A=a_i\oplusj\),\(B=a_j\oplusi\),这里有一个很奇妙的性质(手玩或者......
  • CodeForces-1601B Frog Traveler
    FrogTravelerdp+bfs感觉又像搜索从后往前进行状态转移,像\(bfs\)一样保证当前搜索的是消耗次数最少的状态转移因为是一个连续的区间,因此考虑当前能上升到的最大距......
  • CodeForces-1671E Preorder
    Preorder树型dp+思维\(dp[i]\)表示以\(i\)为根的子树通过变换有多少种不同的先序遍历状态转移方程:当左右子树不同,两个子树交换位置之后,没有重复的出现:\(dp[x]......