[HG]钻石游戏diamond 题解
题面
钻石游戏(diamond)
问题描述:
一个\(M\)行\(N\)列的棋盘,里面放了\(M \times N\)个各种颜色的钻石。
每一次你可以选择任意两个相邻的颜色不同的钻石,进行交换。两个格子相邻的定义是两个格子有一条公共边。
每次交换的分值为通过这次交换后能够形成的最大矩形的面积,具体请见样例。
跟传统的钻石游戏不太一样的是,交换后钻石不会消除。现在告诉你每一次操作,
请输出每一次所能得到的分值。
问题输入:
第一行二个整数\(M,N\)。
接下来\(M\)行\(N\)列,表示第\(I\)行第\(J\)列的钻石的颜色\((1-9)\)。
第\(M+2\)行有一个正整数\(P\),表示钻石交换的次数。
接下来\(P\)行,每行四个正整数\(x1,y1,x2,y2\),\(1 \leq x1,x2 \leq M,1 \leq y1,y2 \leq N\),表示交换\((x1,y1)\)和\((x2,y2)\)的钻石。
保证\((x1,y1),(x2,y2)\)的颜色不相同,并且其必定相邻。
问题输出:
\(P\)行,输出每次交换得到的分值
题解
这道题目的主要失误在于对数据范围估计错误,其实暴力模拟加小优化后的最劣复杂度为\(\Theta(n^2 \times q)\)
约为\(2500\)万,是可以通过的。
这题的暴力很简单,对于每次交换,向外扩展,然后在从内至外枚举,
然后在枚举内部继续往另一个方向扩展,即可计算矩形面积。
稍加分情况讨论即可,代码稍长,但是基本可以复制。
代码
#include <cstdio>
#include <algorithm>
using namespace std;
int read(){
int x = 0; int zf = 1; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
}
//define n the row number, m the col number.
int n, m;
int _max;
int mp[505][505];
int getL(int x, int y, int val){
int cnt = 0;
for (int i = y; i && mp[x][i] == val && (y - i) <= _max; --i)
++cnt;
return cnt;
}
int getR(int x, int y, int val){
int cnt = 0;
for (int i = y; i <= m && mp[x][i] == val && (i - y) <= _max; ++i)
++cnt;
return cnt;
}
int getU(int x, int y, int val){
int cnt = 0;
for (int i = x; i && mp[i][y] == val && (x - i) <= _max; --i)
++cnt;
return cnt;
}
int getD(int x, int y, int val){
int cnt = 0;
for (int i = x; i <= n && mp[i][y] == val && (i - x) <= _max; ++i)
++cnt;
return cnt;
}
int main(){
n = read(), m = read();
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
mp[i][j] = read();
int p = read();
while (p--){
int x1 = read(), y1 = read(), x2 = read(), y2 = read();
if (x1 == x2){
if (y1 > y2)
swap(x1, x2), swap(y1, y2);
}
else if (x1 > x2)
swap(x1, x2), swap(y1, y2);
swap(mp[x1][y1], mp[x2][y2]);
if (x1 == x2){
int ans = 0;
_max = 505; int upper = getL(x1, y1, mp[x1][y1]);
int minu = 505, mind = 505;
for (int i = 1; i <= upper; ++i){
int j = y1 - i + 1;
minu = min(minu, getU(x1, j, mp[x1][y1]));
mind = min(mind, getD(x1, j, mp[x1][y1]));
_max = min(_max, max(minu, mind));
if ((minu + mind - 1) * i > ans)
ans = (minu + mind - 1) * i;
}
minu = 505, mind = 505;
_max = 505, upper = getR(x2, y2, mp[x2][y2]);
for (int i = 1; i <= upper; ++i){
int j = y2 + i - 1;
minu = min(minu, getU(x2, j, mp[x2][y2]));
mind = min(mind, getD(x2, j, mp[x2][y2]));
_max = min(_max, max(minu, mind));
if ((minu + mind - 1) * i > ans)
ans = (minu + mind - 1) * i;
}
printf("%d\n", ans);
}
else{
int ans = 0;
_max = 505; int upper = getU(x1, y1, mp[x1][y1]);
int minl = 505, minr = 505;
for (int i = 1; i <= upper; ++i){
int j = x1 - i + 1;
minl = min(minl, getL(j, y1, mp[x1][y1]));
minr = min(minr, getR(j, y1, mp[x1][y1]));
_max = min(_max, max(minl, minr));
if ((minl + minr - 1) * i > ans)
ans = (minl + minr - 1) * i;
}
minl = 505, minr = 505;
_max = 505, upper = getD(x2, y2, mp[x2][y2]);
for (int i = 1; i <= upper; ++i){
int j = x2 + i - 1;
minl = min(minl, getL(j, y2, mp[x2][y2]));
minr = min(minr, getR(j, y2, mp[x2][y2]));
_max = min(_max, max(minl, minr));
if ((minl + minr - 1) * i > ans)
ans = (minl + minr - 1) * i;
}
printf("%d\n", ans);
}
}
return 0;
}
[HG]钻石游戏diamond 题解的更多相关文章
- 洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题解
P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题目描述 Bessie the cow, always a fan of shiny objects, has ta ...
- 洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 解题报告
P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题目描述 Bessie the cow, always a fan of shiny objects, has ta ...
- 【前缀和】【two-pointer】【贪心】洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题解
解法众多的一道毒瘤题? 题目描述 奶牛Bessie很喜欢闪亮亮的东西(Baling~Baling~),所以她喜欢在她的空余时间开采钻石!她现在已经收集了\(N\)颗不同大小的钻石,现在她想在谷 ...
- java9新特性-8-语法改进:钻石操作符(Diamond Operator)使用升级
1.使用说明 我们将能够与匿名实现类共同使用钻石操作符(diamond operator) 在java8中如下的操作是会报错的: 编译报错信息:'<>' cannot be used ...
- 【ZJ选讲·钻石游戏】
N×M的棋盘(M,N<=500)中,每个格子有一个颜色(颜色数1~9) P次操作(P<=1000),每次给出两个相邻的位置(保证颜色不同,两个格子有一条公共边),把这两个格子交换. 定 ...
- 洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector
题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her s ...
- 洛谷P3143 [USACO16OPEN]钻石收藏家Diamond Collector
题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her s ...
- 洛谷 P2356 【弹珠游戏】题解
自我感觉应该没有用结构体做的吧 这道题其实非常水 很适合初学贪心的同学做一下 我好像没有用贪心做,嘻嘻 首先先读题, 题目中说这个游戏只能消灭当前所在位置的行.列的敌人 首先特判一下: if(tt== ...
- 【luogu P1558 色板游戏】 题解
题目链接:https://www.luogu.org/problemnew/show/P1558 我知道三十棵线段树很暴力,可是我们可以状压啊. 颜色最多30,不会爆int 另外 吐槽评测机 #inc ...
随机推荐
- Django 多数据库联用(同一个APP的models里不同class用不同数据库)
很多网站有多数据库联用的文章,如自强学堂http://code.ziqiangxuetang.com/django/django-multi-database.html 大都只讲解如何让不同的app对 ...
- 科普:PV,UV,VV,IP
1.PV PV即Page View,即页面浏览量或点击量,用户每一次对网站中的每个网页访问均被记录一次.用户对同一页面的多次访问,访问量累计. 2.UV UV即Unique Visitor,是指通过互 ...
- 【Qt开发】V4L2 API详解 背景知识 打开设备设置参数
www.linuxtv.org下,有篇文档详细讲解了V4L2相关知识和体系结构.是V4L2方面最全面的文档.可以通过它学习V4L2的一些思路和想法. http://www.linuxtv.org/do ...
- 剑指Offer编程题(Java实现)——复杂链表的复制
题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...
- CSP-S全国模拟赛第二场 【nan】
A.count 本场比赛最难的题... 隔板法组合数容斥 xjb 搞搞就好了 //by Judge #include<cstdio> #include<iostream> #d ...
- go & cron
https://github.com/robfig/cron - 源码 cron - GoDoc 参考 go---定时任务 cron,gin 静态文件 go语言里比较好用的计划任务调度模块
- HTML DOM中的comfirm()确认对话框
前言 最近在开发中有一个需求大概就是说:表单点击提交按钮首先弹出确认对话框,然后点击确定请求接口,那么问题来了,我们如何确定点击的是确定还是取消呢? 定义和用法 定义 comfirm()确认对话框,用 ...
- CentOS服务器开放端口
拿到服务器之后接着之前的通信步骤进行,却发现怎么也连接不上.最后发现是因为服务器端的端口5000没有开放.下面记录一下开放端口的过程. 使用命令 netstat -anp 查看端口开放情况.如果显示命 ...
- 小程序中页面兼容h5标签的解析
有时候当小程序向后台拿数据是一篇html标签的文章时,把它放进小程序会发现很多标签就不兼容,如果要一个个改又很麻烦,有没有方法可以很快地兼容html标签呢? 有个工具可以做到:wxParse 下载了它 ...
- 解决Chrome浏览器无法自动播放音频视频的问题,Uncaught (in promise) DOMException
转载自:http://www.nooong.com/docs/chrome_video_autoplay.htm 在最新版的Chrome浏览器(以及所有以Chromium为内核的浏览器)中,已不再允许 ...