AtCoder Beginner Contest 347

很快做完了 AB。

然后 C 就不会做了。随便想了个看似正确的就交了,结果 WA*1

后来有交了 4 发,一发比一发离谱。

发现 D 不难,是一个状态数 \(60 \times 60 \times 60\) 的 DP,但是貌似细节很多。写了大约 20 分钟后无伤过了,发现压根没有需要处理的细节。

这时是 57min。

读完 E 的题面,并简单模拟了一下样例就秒了。在 66min 过了。

然后发现 F 是不可做题,就回来肝 C。期间改了无数个写法,想着因为 WA*1 所以肯定是有边界之类的细节没有特判。想到最后也没过。

赛后在 Luogu 发现做法假了。

C - Ideal Holidays

  • 一周有 \(a + b\) 天,其中前 \(a\) 天为假日,后 \(b\) 天为工作日。

    接下来会有 \(n\) 件事情,第 \(i\) 将事情在接下来的第 \(d_i\) 天发生。当前是第 \(1\) 天。

    你不知道今天是星期几。问是否有可能这 \(n\) 件事情都在假日里发生。

  • \(n \le 2 \times 10^5\)\(1 \le a, b \le 10^9\)\(1 \le d_1 < d_2 < \dots < d_n \le 10^9\)

假设当前是星期 \(x\),也就是一个星期中的第 \(x\) 天。那么「所有事情都在假日发生」就可以转化为「所有 \(i \in [1, n]\) 都满足 \((d_i + x) \bmod (a + b) < a\)」。

最朴素的想法就是让除以 \(a + b\) 余数最小的一天成为一个星期的第一天,然后计算出今天是星期 \(x\),再判断是否对于所有事情都满足。

但是这样做会 WA*1。解决方法是如果按照上面方法得不到一个解,就随机某天 \(i\) 并让第 \(b_i\) 天成为这个星期的第一天。处理方法与上面类似。

时间复杂度 \(\Theta(nv)\),其中 \(v\) 是随机次数。这里取 \(v = 50\)

$\color{blue}\textbf{Code}$
int n, a, b, d[N];

bool chk(int p) {
	p %= a + b;
	int t = a + b - p;
	if (!p) t = 0;
	for (int i = 1; i <= n; ++ i )
		if ((d[i] + t) % (a + b) >= a)
			return false;
	return true;
}

void Luogu_UID_748509() {
	fin >> n >> a >> b;
	for (int i = 1; i <= n; ++ i ) {
		fin >> d[i];
		d[i] %= a + b;
	}
	sort(d + 1, d + n + 1);
	bool flg = chk(d[1]);
	for (int i = 1; i <= 50 && !flg; ++ i )
		flg |= chk(d[rand() % n + 1]);
	puts(flg ? "Yes" : "No");
}
posted @ 2024-03-30 22:16  2huk  阅读(202)  评论(0编辑  收藏  举报