Codeforces Round #511 (Div. 2) D. Little C Loves 3 II

codeforces上的一道题,AC代码贴在最后面


目录

1.猜想

2.尝试

3.得出结论


1.猜想

容易得出一个 n * m 的棋盘,有以下结论:

(1) 如果 n * m 为偶数,棋盘最多能放 n * m 个棋子;

(2) 如果 n * m 为奇数,棋盘最多能放 n * (m - 1) 个棋子。

那么我们猜想当 n 和 m 足够大的时候,符合题意的棋子数是不是总能达到这个最大值?


2.尝试

从简单的情况开始尝试找规律,不妨设 n ≤ m,从 n = 1 开始找规律。其中能填满棋盘的情况会用红色标注。

① n = 1

m = 1:结果为0

m = 2:结果为0

m = 3:结果为0

m = 4:结果为2

m = 5:结果为4

m = 6:结果为6,能填满整个棋盘

所以 n = 1 的情况可以以 6 为周期来分析,当且仅当 m % 6 == 0 的时候,可以填满整个棋盘

对于剩余的情况,我们可以构造一个数组 ka[6] = {0, 0, 0, 0, 2, 4},那么最多可符合题意的棋子数量 = (m / 6) * 6 + ka[m % 6]。

② n = 2

m = 2:结果为 0

m = 3:结果为 4

m = 4:结果为 8,能填满

m = 5:结果为 10,能填满

m = 6:结果为 12,能填满

容易得出,任何一个大于等于 8 的偶数 eve 都能表示成 eve = 4 * a + 6 * b 的形式,所以当 m 为偶数时(m ≥ 4),能填满棋盘

而任何一个大于等于 8 的奇数 odd 总能表示成 odd = 5 * a + 4 * b + 6 * c(用归纳法很容易证明),所以当 m 为奇数时(m > 8),能填满棋盘

现在还剩 m = 7 的情况没有考虑,因为用4,5,6三个自然数没办法构造出7,当 m = 7 时,结果为 12,不能填满。

所以总结一下 n = 2 的结论

当 m = 2、m = 3、m = 7 时无法填满,是特殊情况;

其 m 不为 2 或 3 或 7 时,无论奇数还是偶数,均可填满棋盘,达到最大值 n * m。

③ n = 3

m = 3 :结果为 8,刚好达到 n * m - 1 这个最大值

m = 4 :结果为 12,能填满

m = 6 :结果为 18,能填满

由于“任何大于等于 8 的偶数都可以用 4 和 6 构造出来”,所以当 m 为偶数时(m ≥ 4),能填满棋盘

而当 m 为奇数时,可以把棋盘拆成一个 n * (m - 3) 和 n * 3 的棋盘(n = 3),

对于 n * (m - 3) 的棋盘,由于 m - 3 一定是大于等于 2 的偶数,所以结合②的结论,能填满

对于 n * 3 的棋盘,恰好差一个棋格没法填,

因此 当 m 为奇数时,虽然不能填满,但是能达到 n * m - 1 这个最大可容纳棋子数。

总结一下 n = 3的结论

若 m 为偶数,能填满棋盘;

若 m 为奇数,恰好有一个棋格多余,能达到奇数棋盘的最大值 n * m - 1。

④ n = 4

先取消掉 n < m 的假设,

m = 2 :结果为 8,能填满

m = 3 :结果为 12,能填满

由于 m = 2 的时候能填满,所以当 m 为偶数时,一定能填满

若 m 为奇数,同样可以拆分成 n * (m - 3) 和 n * 3的棋盘,

n * (m - 3) 的棋盘即 n = 4,m` 为偶数的棋盘,一定能填满,

4 * 3 的棋盘也能填满,所以当 m 为奇数时,也一定能填满

结论:

无论 m 为奇数或是偶数,一定都能填满,达到最大值 n * m

⑤ n = 5

先取消掉 n < m 的假设,

m = 2 :结果为 10,能填满

m = 3 :结果为 15,能填满

与④中的推理方法类似,拆成 n * (m - 3) 和 n * 3 的棋盘可以得出如下结论

若 m 为偶数,一定能填满

若 m 为奇数,虽然不能填满,但是能达到最大值 n * m - 1。

⑥ n = 6

由于①中说过 1 * 6 的棋盘是可以填满的,所以无论 m 为奇数还是偶数,总能填满


3.得出结论

下面对 n,m > 6 的情况做分析。

还是以1.猜想中的猜想为基准,分成三种情况:n 和 m 都是偶数、n 和 m 都是奇数、n 和 m 一个为奇数,一个为偶数。

A. n 和 m 都是偶数

结合第2部分②④⑥中 m 为偶数时的结论,得出此情况一定能填满棋盘

B. n 和 m 一个为奇数,一个为偶数

不妨设 m 是其中的奇数。

还是拆分成 n * (m - 3) 和 n * 3 两个棋盘,

n * (m - 3) 棋盘就是A中“两个都是偶数”的棋盘,所以能填满,

n * 3 棋盘对应的是2的③中"n = 3,m 为偶数"的棋盘,也能填满。

所以此情况一定能填满棋盘

C. n 和 m 都是奇数

还是用拆分的方法,拆成 n * (m - 3) 和 n * 3 两个棋盘,

n * (m - 3) 棋盘就是B中“一个是奇数一个是偶数”的棋盘,所以能填满,

n * 3 棋盘对应的是2的③中“n = 3, m 为奇数”的棋盘,不能填满,刚好空一个棋格,所以能达到奇数棋盘的最大值 n * m - 1,

所以此情况的最大容纳棋子数量为 n * m - 1。

结合本小节A、B、C和第二小节①②③④⑤⑥的结论,可以得出最终结论如下:

if (n == 1)
    按照①单独分析;
else if (n == 2)
    按照②单独分析,注意 m = 7 的情况;
else if (n * m 为偶数)
    结果是 n * m;
else // n * m 均为奇数
    结果是 n * m - 1;

4.代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define MAXN 3e5 + 10
#define MAXNUM 1.5e7 + 10

const long ka[6] = { 0, 0, 0, 0, 2, 4 };

int main()
{
	long long n, m;
	while(cin >> n >> m)
	{
		if (n > m)
		{
			int tmp = n; n = m; m = tmp;
		}
		long long ret;
		if (n == 1) ret = m / 6 * 6 + ka[m % 6];
		else if (n == 2)
		{
			if (m == 2) ret = 0;
			else if (m == 3) ret = 4;
			else if (m == 7) ret = 12;
			else ret = n * m;
		}
		else {
			if (n % 2 && m % 2) ret = n * m - 1;
			else ret = n * m;
		}

		cout << ret << endl;
	}

	return 0;
}

 

 

你可能感兴趣的:(Codeforces)