1. 程式人生 > 其它 >CF1368F Lamps on a Circle 題解

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;
	}
}