【拼图问题】B. Coloring Rectangles

题目来源

Dashboard - Codeforces Round #755 (Div. 2, based on Technocup 2022 Elimination Round 2) - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1589

题干

 

解释

本解释为个人的拙劣思路,不代表官方思路(个人认为还可以优化)

因为要保证每个被分割的方格里的方块都是颜色相隔的,最小的子方格情形只有两种

 三个一组的子方格-S3 两个一组的子方格-S2
在n行m列的方格中,因为我们无法判断一个动态问题 

[m/3]*n ? [n/3]*m

所以我们都会计算一遍让n和m分别作为行和列进行最小值判断

单行填入函数

首先介绍一下单行填入函数

扫描二维码关注公众号,回复: 13179019 查看本文章

 如果x(列数)为3的倍数,则直接填入x/3个S3

如果余一,则填入X/3-1个S3,再加一个S2

如果余二 ,则填入X/3个S3,再加一个S2

插入规则

总是先将 S3 竖着放入方格

假设LINE正好是的3的倍数,则最小这么填入

假设LINE是3的倍数余1

这时只需要横过来填入最后一行就可以啦(按照单行填入函数)

 假设LINE是3的倍数余2

这时易证一个结论如果横过来填入S3与S2会比竖着填入S2要小

ROW列数为Y,则竖过来填入S2需要S2*Y,横过来则按照单行填入函数进行

Y为3的倍数,S2*Y>Y/3*2

Y不为3的倍数,S2*Y>([Y/3]+1)*2;(当Y为1的时候虽然这时候计算会不满足,当交换行列数m,n之后,仍旧能取到正确的最小值)

代码段

int num2(int x)
{
	int num2=0;
	if (x % 3 == 1)num2 = x / 3 -1+2;
	if (x % 3 == 2)num2 = x / 3 + 1;
	if (x % 3 == 0)num2 = x / 3;
	return num2;
}

int num(int x,int y)
{
	int num1=0;
	if (x % 3 == 1)num1 = x /3*y+num2(y);
	if (x % 3 == 2)num1 = (x / 3 )*y+num2(y)*2;
	if (x % 3 == 0)num1= x / 3*y;
	return num1;
}
void solve()
{
	int n, m;
	cin >> n>>m;
	int ans = min(num(m,n),num(n,m));
	cout << ans << endl;
}

猜你喜欢

转载自blog.csdn.net/nathanqian123/article/details/121322964