当前位置: 首页 > article >正文

【题解】AT_abc386_d AtCoder Beginner Contest 386 D Diagonal Separation

题目传送门

  • 原题面链接

题目大意

给你一个 N × N N \times N N×N 的二维矩阵,矩阵里有三类元素:黑(B)、白(W)以及不确定。有 M M M 个格子的颜色已给出,剩余的 N 2 − M N^2-M N2M 个格子都是不确定,现在要给它们涂颜色,自然是黑白任选其一。要求格子满足以下条件:

  • 对于每一行,存在整数 i i i 满足 0 ≤ i ≤ N 0 \le i \le N 0iN 且这一行前 i i i 个格子都是黑格,其余均为白格。
  • 对于每一列,存在整数 i i i 满足 0 ≤ i ≤ N 0 \le i \le N 0iN 且这一列前 i i i 个格子都是黑格,其余均为白格。

已经有颜色的格子不能修改颜色,请判断这样可不可行。

思路

看一眼数据范围,蒙了: N ≤ 1 e 9 N \le 1e9 N1e9 是给人做的吗??时间空间都会炸啊!别急,咱们想个 O ( M ) O(M) O(M) 或者 O ( M ∗ log ⁡ M ) O(M*\log M) O(MlogM) 时间复杂度的做法,然后用 C++ std::map 来存储不就好了吗?!C党P党对不起,你们手写离散化吧,后面二分什么的自己看着办,这篇题解主要使用STL。

大家思考一个问题:如果在某一行某一位置有一个白格,那么请问要是它后面还有一个黑格时,是否可行?(对于“列”也是一样的)。答案显然是否定的,这个没什么争议吧,不明白的看题。好的,接下来要是就写这一点点,那么恭喜你,样例四过不了。

Sample Input 4

2289 10
1700 1083 W
528 967 B
1789 211 W
518 1708 W
1036 779 B
136 657 B
759 1497 B
902 1309 B
1814 712 B
936 763 B

Sample Output 4

No

咦?根据前面的推论,这里一点问题也没有啊?!

数据真大,咱们画个简单的图解释一下。

请问这个图是否可行?答案是否定的,原因见下图。

好的,所以如果某个白格身后的某一列的这一行及以下有黑格(好像绕口令,自己理解一下),那么它也是不可行的。 列也是一样的。这一堆东西让我们想到了 二分 和二维map处理(详见代码)。

代码

/*
fx[x][y]=1 fy[y][x]=1 代表 (x, y) 有一个黑格
不懂迭代器的请自学,本文限于篇幅不再讲解
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

int n, m;
map<int, map<int, int> > fx, fy;

struct node
{
	int x, y;
	char c;
} ;

node p[200010];

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int x, y;
		char c;
		cin >> x >> y >> c;
		p[i] = (node){x, y, c};
		if (c == 'B')
		{
			fx[x][y] = 1;
			fy[y][x] = 1;
		}
	}
	for (int i = 1; i <= m; i++)
	{
		int x = p[i].x;
		int y = p[i].y;
		if (p[i].c == 'B')
			continue;
		map<int, map<int, int> >::iterator po = fx.lower_bound(x);
		map<int, int>::iterator pos;
		if (po != fx.end()) pos = fx[po->first].lower_bound(y);
		if (po != fx.end() && pos != fx[po->first].end())
		{
			cout << "No" << endl;
			return 0;
		}
		po = fy.lower_bound(y);
		if (po != fy.end()) pos = fy[po->first].lower_bound(x);
		if (po != fy.end() && pos != fy[po->first].end())
		{
			cout << "No" << endl;
			return 0;
		}
	}
	cout << "Yes" << endl;
	return 0;
}

总结

是的,这一堆乱七八糟的东西居然 AC 了。

显然这不是什么最优解,时间复杂度也令人不悦,如果您有其他做法或优化请在评论区留言或私信,谢谢。

参考资料及文献

https://zh.cppreference.com/w/cpp/container/map


http://www.kler.cn/a/461102.html

相关文章:

  • Codigger集成Copilot:智能编程助手
  • Servlet解析
  • 朱姆沃尔特隐身战舰:从失败到威慑
  • 【Matlab算法】基于改进人工势场法的移动机器人路径规划研究(附MATLAB完整代码)
  • 15. 接雨水
  • 【VBA】EXCEL - VBA 遍历工作表的 5 种方法,以及注意事项
  • 【每日学点鸿蒙知识】List+Swipe滑动冲突、下拉刷新、编译错误定位、监听生命周期、上架应用市场要求
  • 分布饼状图——开发解释——未来之窗行业应用跨平台架构
  • 零售小程序怎么自己搭建?开个小卖铺如何留住客户?
  • mybatisPlus基础
  • 服务器数据恢复—磁盘阵列中多块硬盘离线导致存储中数据无法访问的数据恢复
  • SpringMVC中的拦截器
  • MVC 架构学习笔记
  • CUTLASS:高性能 CUDA 线性代数模板库详解
  • 过圆外一点与圆相切的直线
  • 表单验证不生效
  • 前端Monorepo实践分享
  • GXUOJ-算法-第四次作业(圆排列、连续邮资、n皇后、符号三角形)
  • 「下载」智慧文旅运营综合平台解决方案:整体架构,核心功能设计
  • Rabbitmq追问2
  • UniApp 组件的深度运用
  • 【时时三省】(C语言基础)动态内存函数calloc
  • 活动安排.
  • nginx-nginx的缓存集成
  • Tube Qualify弯管测量系统在汽车管路三维检测中的应用
  • 08.VSCODE:内嵌MSYS2及三方库UTF8-CPP的实战