画作

news/2024/12/28 11:32:17/

题目

题目描述
C C C 喜欢作画, 尤其喜欢仅使用黑白两色作画。黑白的不一定是遗照。

画布可以看成 r × c r\times c r×c 的单元格矩阵。现在小 C C C 构思好了他的画,准备动笔。初始时画布是全白的,他每一次下笔可以将一个四连通的部分涂成黑色或白色。相邻格子定义为有公共边的格子。称 S S S 为四连通,当且仅当 S S S 中任意两个格子之间都存在一条 S S S 内路径,满足只在相邻格子间移动。

你需要告诉他,最少需要下笔多少次才能完成画作。

数据范围与提示
max ⁡ ( r , c ) ≤ 50 \max(r,c)\le 50 max(r,c)50 。部分分也很难,就不给出了。

思路

话说这个矩阵是连通的,不会真的有人不知道吧 😒

直接猜结论:存在一种最优方案,每次的操作是上一次操作的子集,并且颜色相反。像俄罗斯套娃。

OI结论都要证明的话,跟数竞有什么区别? 我们来试着证明一下这个结论。用归纳法。

不妨设原来的操作区间依次是 S 1 , S 2 , … , S k S_1,S_2,\dots,S_k S1,S2,,Sk ,已经满足了这个结论,现在要操作 T T T 。由于整张画布最初是白色的,规定 S 0 S_0 S0 为整个画布,并且其颜色为白色。显然 T ⊆ S 0 T\subseteq S_0 TS0

我们循环执行如下操作,如同迭代:

  • 找一个最大的 x x x 使得 T ⊆ S x T\subseteq S_{x} TSx 。如果 x = k x=k x=k 则结论成立,退出迭代。否则有 T ⊆ S x + 1 T\subseteq S_{x+1} TSx+1 不成立,继续下一步。
  • 如果 T T T S x S_x Sx 是同色的,那么 T T T S x − S x + 1 S_x-S_{x+1} SxSx+1 中的部分无用。所以将 T T T 修改为 T ∩ S x + 1 T\cap S_{x+1} TSx+1 ,回到第一步。容易发现下一次循环的 x x x 必定增大。
  • 如果 T T T S x S_x Sx 是不同色的,那么 T T T S x + 1 S_{x+1} Sx+1 同色。分两种情况。
    1. T T T S x + 1 S_{x+1} Sx+1 没有交集,必定存在一个四连通 M ⊆ S x M\subseteq S_x MSx 满足 S x + 1 ⊆ M S_{x+1}\subseteq M Sx+1M T ⊆ M T\subseteq M TM 。将 S x + 1 S_{x+1} Sx+1 扩充为 M M M ,将 T T T 更改为 M − T − S x M-T-S_{x} MTSx ,也就是将 S x S_{x} Sx T T T 连接起来的部分,然后反转颜色。不难发现 S S S 序列仍然是满足包含关系的。回到第一步。容易发现下一次的 x x x 必定增大。
    1. T T T S x + 1 S_{x+1} Sx+1 有交集,令 S x + 1 ′ = S x + 1 ∪ T , T ′ = T ∩ S x + 1 S'_{x+1}=S_{x+1}\cup T,\;T'=T\cap S_{x+1} Sx+1=Sx+1T,T=TSx+1 即可。回到第一步。容易发现下一次的 x x x 必定增大。

由于 x x x 总是在增大,而 k k k 是不变的,所以迭代将会有出口 x = k x=k x=k ,故结论成立。

有了这个结论,并不好做。但是 时光倒流 就很简单,就像穿棉袄,一圈一圈的增加。最终答案就是 “圈” 的数量。相邻的格子连边,异色则边权为 1 1 1 ,同色则为 0 0 0 ,这样就实现了 “圈” 之间的转移为 1 1 1 ,于是最短路长度即为 “圈” 数 − 1 -1 1 了。于是你枚举一下,哪个点是最后被上色的,其贡献就是它到所有黑点的最短路的最大值。所有贡献取 min ⁡ \min min 就是答案。

复杂度 O ( r 2 c 2 ) \mathcal O(r^2c^2) O(r2c2) 。不会真的有人不会 b f s \tt bfs bfs 吧?

代码

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
inline int readint(){int a = 0; char c = getchar(), f = 1;for(; c<'0'||c>'9'; c=getchar())if(c == '-') f = -f;for(; '0'<=c&&c<='9'; c=getchar())a = (a<<3)+(a<<1)+(c^48);return a*f;
}const int MaxN = 51;
const int dir[][2] = {{0,1},{1,0},{0,-1},{-1,0}
};
int dis[MaxN][MaxN], n, m;
char maze[MaxN][MaxN+5];
int q[MaxN*MaxN], head, tail;
void addMore(int x,int y){ // 连坐q[++ tail] = x*m+y-1;for(int i=0,tx,ty; i<4; ++i){tx = x+dir[i][0];ty = y+dir[i][1];if(1 <= tx && tx <= n)if(1 <= ty && ty <= m)if(dis[tx][ty] == -1)if(maze[x][y] == maze[tx][ty]){dis[tx][ty] = dis[x][y];addMore(tx,ty);}}
}
int bfs(int x,int y){for(int i=1; i<=n; ++i)for(int j=1; j<=m; ++j)dis[i][j] = -1;head = 0, tail = -1; // emptydis[x][y] = 0; // initaddMore(x,y); // 加入整个点while(head <= tail){int x = q[head]/m, tox;int y = q[head]%m+1;++ head; // pop_frontfor(int i=0,toy; i<4; ++i){tox = x+dir[i][0];toy = y+dir[i][1];if(dis[tox][toy] == -1){dis[tox][toy] = dis[x][y]+1;addMore(tox,toy);}}}int res = 0;for(int i=1; i<=n; ++i)for(int j=1; j<=m; ++j)if(maze[i][j] == '1')res = max(res,dis[i][j]);return res;
}int main(){n = readint(), m = readint();for(int i=1; i<=n; ++i)scanf("%s",maze[i]+1);int ans = n*m; // 最短路 = 圈数-1for(int i=1; i<=n; ++i)for(int j=1; j<=m; ++j)ans = min(ans,bfs(i,j));printf("%d\n",ans+1);return 0;
}

http://www.ppmy.cn/news/138632.html

相关文章

幽默 滑稽 及 其他

我总结这个&#xff0c;主要是汇总一下收集到的资料。update 2009-03-12 00:10 原来打算写一个收集国外幽默和中国幽默的异同。但是渐渐跑题了。这里收集的这些词的解释&#xff0c;又怎么可能在生活中找到严格的例子呢&#xff1f;我已经完全分不开它们了。有些“幽默”在微笑…

计算机画图软件如何画出眼泪,【推荐】女生哭泣的表情怎么画?教你如何绘画出让人动容的泪水...

原标题&#xff1a;【推荐】女生哭泣的表情怎么画&#xff1f;教你如何绘画出让人动容的泪水 哭泣表情怎么画&#xff1f;女生哭泣的表情怎么画&#xff1f;学习绘画难吗&#xff1f;怎样才能学好绘画&#xff1f;想必这些哦都市绘画初学者们经常在想的问题吧&#xff0c;女生就…

笑哭了

http://code.google.com/p/windows-config/wiki/TourDeBabel #title Tour De Babel 通天塔导游 (译注&#xff1a;圣经记载&#xff1a;在远古的时候&#xff0c;人类都使用一种语言&#xff0c;全世界的人决定一起造一座通天的塔&#xff0c;就是巴别塔&#xff0c;后来被上…

逛画展

1. 题目简介 博览馆正在展出由世上最佳的 M 位画家所画的图画。 wangjy想到博览馆去看这几位大师的作品。 可是&#xff0c;那里的博览馆有一个很奇怪的规定&#xff0c;就是在购买门票时必须说明两个数字&#xff0c;a和b&#xff0c;代表他要看展览中的第 a 幅至第 b 幅画(包…

偷笑

今天心情好极了&#xff0c;真的是幸福像花儿一样绽放。 想到什么都想笑&#xff0c;笑咱么矿大姑娘取得昨天CUBA的胜利&#xff0c;笑昨天老公说金喜善和成龙&#xff0c;笑群里那些人的所问非所答&#xff0c;笑花痴姑娘们看帅哥的口水&#xff0c;笑我今天带的苹果真甜。。 …

笑不笑由你

kam和Ivis在WC里面是同桌&#xff0c;别人总说那两个人每天总有笑不完的东西&#xff0c;现在拿一天的摘录给大家分享一下&#xff0c;呵呵。 8点到公司&#xff0c;Ivis先给kam5个智力题—— 第一题 你参加赛跑&#xff0c;追过第2名&#xff0c;你是第几名&#xff1f; 回…

画画的玩意

MainActivity //本来应该 //setContentView(R.layout.activity_main); //但是应该修改成以下的代码 setContentView(new PaintView(this)); PaintView类继承一个View类 PaintView extends View //画笔 private Paint mPaint; public PaintView(Context c…

画画

晚上在教弟弟用painter画画&#xff0c;让他也找点乐趣&#xff0c;多学些东西&#xff0c;想不到一晃又到凌晨&#xff0c;其实自己有很多事在等着去办&#xff0c;最近一直担搁着&#xff0c;想想我也好几天没有涂鸦了~~现在也来上一张吧&#xff0c;嘿嘿~~现在才准备开始&am…