码迷,mamicode.com
首页 > 其他好文 > 详细

「ZJOI2007」「LuoguP1169」棋盘制作(并查集

时间:2018-10-18 00:48:21      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:return   lin   https   orange   博弈   def   最大   int   art   

题目描述

国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源于易经的思想,棋盘是一个8×88 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。

而我们的主人公小Q,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则。

小Q找到了一张由N×MN \times MN×M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。

不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。

于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?

输入输出格式

输入格式:

包含两个整数NNN和MMM,分别表示矩形纸片的长和宽。接下来的NNN行包含一个N ×MN \ \times MN ×M的010101矩阵,表示这张矩形纸片的颜色(000表示白色,111表示黑色)。

输出格式:

包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。

输入输出样例

输入样例#1: 复制
3 3
1 0 1
0 1 0
1 0 0
输出样例#1: 复制
4
6

说明

对于20%20\%20%的数据,N,M≤80N, M ≤ 80N,M80

对于40%40\%40%的数据,N,M≤400N, M ≤ 400N,M400

对于100%100\%100%的数据,N,M≤2000N, M ≤ 2000N,M2000

题解

某天中午去吃超好吃的鱼粉,路上,一位选手问我们,

你知道悬线法是什么吗?!

我不知道,于是我问他是干嘛的,于是他洋洋洒洒的摆出了这道题。

我kiao,这不就是我校传了好几届的最大矩阵题吗?!

原题差不多长这样(点这里!)

然后我把那道题改造了一下,成功AC。

————————————

跟原题不同的是,我们传承前缀和时的条件改为此位和上一位不同。

并且和左右接通时,判断是否不同。如果相同就不连。

 1 /*
 2     qwerta
 3     P1169 [ZJOI2007]棋盘制作
 4     Accepted
 5     100
 6     代码 C++,1.5KB
 7     提交时间 2018-10-14 21:34:02
 8     耗时/内存
 9     29ms, 688KB
10 */
11 // luogu-judger-enable-o2
12 #include<iostream>
13 #include<cstdio>
14 #include<queue>
15 #include<cmath>
16 using namespace std;
17 #define R register
18 int s[2003];
19 int a[2003];
20 struct emm{
21     int nod,v;
22 };
23 struct cmp{
24     bool operator()(emm qaq,emm qwq){
25         return qaq.v<qwq.v;
26     }
27 };
28 priority_queue<emm,vector<emm>,cmp>q;
29 int siz[2003],fa[2003];
30 bool sf[2003];
31 int fifa(int x)
32 {
33     if(fa[x]==x)return x;
34     return fa[x]=fifa(fa[x]);
35 }
36 inline void con(int x,int y)
37 {
38     int u=fifa(x),v=fifa(y);
39     siz[u]+=siz[v];
40     fa[v]=u;
41     return;
42 }
43 inline int read()
44 {
45     char ch=getchar();
46     int x=0;
47     while(!isdigit(ch))ch=getchar();
48     if(isdigit(ch)){if(ch==1)x=1;ch=getchar();}
49     return x;
50 }
51 int main()
52 {
53     //freopen("a.in","r",stdin);
54     int n,m;
55     scanf("%d%d",&n,&m);
56     int ansz=0,ansc=0;
57     for(R int i=1;i<=n;++i)
58     {
59         for(R int i=1;i<=m;++i)
60         {
61             int x=read();
62             if(a[i]+x==1)s[i]++;
63             else s[i]=1;
64             a[i]=x;
65             q.push((emm){i,s[i]});
66         }
67         for(R int i=1;i<=m;++i)
68           fa[i]=i,siz[i]=1,sf[i]=0;
69         a[0]=a[m+1]=2;
70         while(!q.empty())
71         {
72             int i=q.top().nod,x=q.top().v;q.pop();
73             sf[i]=1;
74             if(a[i-1]+a[i]==1&&sf[i-1])
75               con(i-1,i);
76             if(a[i]+a[i+1]==1&&sf[i+1])
77               con(i,i+1);
78             int fi=fifa(i),mi=min(siz[fi],x);
79             ansz=max(ansz,mi*mi);
80             ansc=max(ansc,siz[fi]*x);
81         }
82     }
83     printf("%d\n%d",ansz,ansc);
84     return 0;
85 }

 

「ZJOI2007」「LuoguP1169」棋盘制作(并查集

标签:return   lin   https   orange   博弈   def   最大   int   art   

原文地址:https://www.cnblogs.com/qwerta/p/9807389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!