CF1368F Lamps on a Circle 题解

Codeforces
Luogu

Description.

\(n\) 盏灯排成一圈,Alice 点亮任意 \(k\) 盏,Bob 熄灭 \(k\) 盏连续的。
你需要最大化亮着的灯数,在不超过 \(10^4\) 次交互中达到。

\(n\le 10^3\)

Solution.

首先考虑最大上限是什么。
如果是 \(k\),那每次相当于找到 \(k\) 个亮后不应该存在有连续 \(k\) 个是熄灭状态的。
相当于目标状态不存在连续 \(k\) 个点亮。
最优状态肯定是隔 \(k-1\) 个亮一个,个数大概是 \(n-k-1-\frac{n-1}{k}\)
然后 \(k=\sqrt n\) 时最优。

考虑如何构造。
每次选出一些目标点,直接染。
然后每次至多可以使答案 \(+1\),然后就做完了。

Coding.

点击查看代码
//Coded by Kamiyama_Shiki on 2021.11.03 {{{
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
int n,K;char vs[10005];
inline int Calc(int k) {return n-k-(n-1)/k;}
int main()
{
	read(n);int mx=1,cnt=0;
	for(int i=1;i<=n;i++) if(Calc(mx)<Calc(i)) mx=i;
	if(Calc(mx)<=0) return puts("0"),0;
	while(1)
	{
		printf("%d ",mx);int res=mx;
		for(int i=1;i<=n;i++) if(i%mx!=1&&!vs[i]&&res-->0) vs[i]=1,cnt++,printf("%d ",i);
		putchar('\n'),fflush(stdout);int w;read(w);
		for(int i=1,ps;i<=mx;i++) ps=(i+w-2)%n+1,cnt-=vs[ps],vs[ps]=0;
		if(cnt==Calc(mx)) return puts("0"),fflush(stdout),0;
	}
}
原文地址:https://www.cnblogs.com/pealfrog/p/15505930.html