首页 > 其他分享 >CF1181C Flag 题解

CF1181C Flag 题解

时间:2022-11-17 16:37:00浏览次数:54  
标签:颜色 int 题解 Flag 宽度 && ans CF1181C include

题意:问在一个 \(n\times m\) 的平面里有多少旗帜,旗帜的定义是三条宽度相等的带子,相邻的带子颜色不能相同(第一和第三条的颜色可以相同)。

考虑以左上角统计旗帜,预处理每个点向下走遇到颜色不同的点的距离记为 \(d=f_{i,j}\),设当前的点颜色为 \(a_{i,j}\),那么必须满足 f[i+d][j]==d&&f[i+2*d][j]>=d&&a[i][j]!=a[i+d][j]&&a[i+d][j]!=a[i+2*d][j]f[i+d][j]==d 是为了确保第一和第二条的宽度相等,f[i+2*d][j]>=d 是为了保证第三条的宽度至少是第一第二条的宽度,至于 a[i][j]!=a[i+d][j]&&a[i+d][j]!=a[i+2*d][j] 是为了保证第一和第二条,第二和第三条的颜色不同。
现在只是确定了向下的方向,固定左上角的点,第二第三条的颜色与宽度是确定的,但是向右延申的距离是不知道的,比如这个(蓝粉白粉蓝):

BBBBBBBBBB
PPPPPPPPPP
WWWWWWWWWW
PPPPPPPPPP
BBBBBBBBBB

在枚举到 \((1,1)\) 这个点时,已经确定每条的高度是 \(1\) 并且颜色是 \(\text{B,P,W}\) 但是没法快速统计出右边能延申几个,不妨把贡献挂在右边的节点上,比如 \((1,1)\) 的贡献是 \(1\),\((1,2)\) 的贡献是 \(2\),\((1,3)\) 的贡献是 \(3\),这样就很好办了。
记录往下是否可行为条件 \(1\),和左边是否一样为条件 \(2\),因为要枚举每个点,先枚举行,在枚举列时记录一个 \(k\),如果不满足条件 \(1\) 那么 \(k=0\),否则进行判断,如果这三带和前面那一带一模一样,也就是 f[i][j-1]==d&&f[i+d][j-1]==d&&f[i+2*d][j-1]>=d&&a[i][j-1]==a[i][j]&&a[i+d][j-1]==a[i+d][j]&&a[i+2*d][j-1]==a[i+2*d][j] 那么就 \(k=k+1\),否则 \(k=1\),执行完操作后 \(ans=ans+k\) 就行了。

代码:

//不向焦虑与抑郁投降,这个世界终会有我们存在的地方。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cassert>
#include<tuple>
#include<ctime>
#include<random>
using std::cin;using std::cout;
using loli=long long;
constexpr int N=1002;
int n,m,f[N][N];
char a[N][N];
loli ans;
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	std::ios::sync_with_stdio(false);cin.tie(nullptr);
	cin>>n>>m;
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
	for(int i=n;i>=1;i--)for(int j=1;j<=m;j++)
		if(a[i][j]==a[i+1][j])f[i][j]=f[i+1][j]+1;else f[i][j]=1;
	for(int i=1;i<=n;i++)for(int j=1,k=0;j<=m;j++){
		int d=f[i][j];
		if(i+3*d-1<=n&&f[i+d][j]==d&&f[i+2*d][j]>=d&&a[i][j]!=a[i+d][j]&&a[i+d][j]!=a[i+2*d][j]){
			if(f[i][j-1]==d&&f[i+d][j-1]==d&&f[i+2*d][j-1]>=d&&a[i][j-1]==a[i][j]&&a[i+d][j-1]==a[i+d][j]&&a[i+2*d][j-1]==a[i+2*d][j])
				k++;
			else k=1;
		}else k=0;
		ans+=k;
	}
	cout<<ans;
	return 0;
}

标签:颜色,int,题解,Flag,宽度,&&,ans,CF1181C,include
From: https://www.cnblogs.com/bxjz/p/CF1181C.html

相关文章

  • 小程序获取不到用户头像和昵称返回微信用户问题解决,即小程序授权获取用户头像规则调整
    最近好多同学在学习石头哥小程序课程的时候,遇到了下面这样的问题,在小程序授权获取用户头像和昵称时,获取到的是下面这样的。到底是什么原因导致的呢,去小程序官方文档一看,又是......
  • Codeforces Gym 100958 E Cellular Automaton (Makoto rng_58 Soejima contest) 题解
    题目链接其实"序列中1的数量有限"是一个非常重要的条件。这意味着我们可以找到序列中的第一个1和最后一个1。考虑这样一件事情:初始时我们把一个长度为\(2^{2w+1}\)的"滑......
  • CF707E Garlands 题解
    简要题意:在一个\(n\timesm\)的矩阵(\(n,m\le2000\))中,每个点都有个灯,刚开始所有灯都是亮的,每个灯都有一个颜色(\(k\le2000\))和一个权值,保证所有颜色相同的点是联通块。现......
  • UVA1331 题解
    前言题目传送门!更好的阅读体验?计算几何、区间DP。思路......
  • T292306 01最短路 题解
    又是一个找不到题目所以自己写的题。。。40迪杰斯特拉,但是搞不懂为什么是wa而不是re的#include<bits/stdc++.h>#definefor1(i,a,b)for(inti=a;i<=b;i++)#definell......
  • cmake报错找不到Glog、Gflags、Eigen3
    报错内容Bynotproviding"FindGlog.cmake"inCMAKE_MODULE_PATHthisprojecthasaskedCMaketofindapackageconfigurationfileprovidedby"Glog",butCMake......
  • 紫罗兰题解
    题意概述给定一张\(n\)个顶点\(m\)条边的无向图,顶点的编号在\(1\simn\)内,第\(i\)条无向边连接着顶点\(x_i\)与\(y_i\)。我们称顶点\(v_0,v_2,\cdots,v_{k......
  • DTOJ 2022-11-15 测试 题解
    测试成果100+100+50+10=260还行吧(虽然T2做法很迷惑)A惊鸿(grace)DTOJP6367题面大意给定一个\(n\)行\(m\)列的仅包含小写字母的矩阵\(A\)。求从\((1,1)\)......
  • 长春花题解
    题意概述给定一个素数\(p\),对每个\(0\lex<p\),设\(f(x)\)表示一个最小的非负整数\(a\),使得存在一个非负整数\(b\),满足\((a^2+b^2)\bmodp=x\)。现在,你想要......
  • LeetCode 题解 1922. 统计好数字的数目
    1922.统计好数字的数目-力扣(Leetcode)题解思路一:快速幂#defineMOD1000000007longlongpower(intn,longlongtimes){if(times==1)returnn;if(ti......