yuwj  

codeforces 1058 div2

写在前面

图片

喜报,上巨分了

第一次出 D 的说

这篇题解是赛时还剩 1h 直接放弃E写得,现在只希望赶紧结束,不然加分加少了,哎哎哎

难道这就是量变临界点吗?

看来 10 天 100 道的神迹还是很有效果的www

这下是正式解锁 1700 了hhh

A

这个SB题WA了三发,一开始题都没读懂,一脸懵逼

思路:

就是 mex

void Solve(){
	bool ok = 0;
	cin >> n;
	vector<int> vis(105);
	for(int i=1;i<=n;++i) cin >> x, vis[x]++;
	int ans = 0;
	while(vis[ans]) ++ ans;
	cout << ans << '\n';
}

B

思路:

发现只要看与前一个数字的差值就好了,如果差值 d < i,则就从前面加过来,否则就必须新开一个数才够用

从前面哪个加过来呢?发现从 i 位置往前看,每与前一个数字相同,都会贡献1,所以直接 ans[i] = ans[i-d] 即可

void Solve(){
	cin >> n;
	vector<int> b(n+1), ans(n+1);
	int now = 1;
	for(int i=1;i<=n;++i)cin >> b[i];
	ans[1] = 1;
	for(int i=2;i<=n;++i){
		int d = b[i] - b[i-1];
		if(d >= i) ans[i] = ++now;
		else ans[i] = ans[i-d];
	}
	
	For(i,1,n) cout << ans[i] << " \n"[i==n];
}

C

思路:

发现其实就是二进制字符串最前面的 1 和最后面的 1 是回文的,

然后奇数的时候必须中心是 0,否则无法构造,不可能对称串中心不同


// 最左边的 1 和 最右边的 1 中间得是回文串
void Solve(){
	cin >> n;
	string s="";
	for(int i=__lg(n); i>=0; --i){
		int u = ((n>>i)&1);
		s += char(u+'0');
	}
	if(n == 0) {puts("YES"); return;}
	// cerr << s << '\n';

	int l = -1, r = 0;
	for(int i=0; i < s.size(); ++i)if(s[i] == '1'){
		if(l<0) l = i;
		r = i;
	}

	bool ok = 1;
	for(int i = l; i <= l + (r-l+1)/2; ++i){
		if(s[i] != s[r-i]) ok = 0;
	}
	int len = (r-l+1), mid = l + len/2;
	if(len&1 && s[mid] != '0') ok = 0;
	puts(ok?"YES":"NO");
}

D

思路:

就是先 2n 扫一遍,然后 n 次反查就结束了

第一次 2n 扫一遍的时候,如果返回 0,就加入st表示当前拿到的下标集合,否则就ans[i]=res,不加入下标,直接查到答案

扫完之后将下标分成两类,第一次出现的所有下标和第二次出现的所有下标,再用 n 次把第一次出现的所有下标查到就完事了

void Solve(){
	cin >> n;
	vector<int> ans(2*n+1);
	
	set<int> st;
	for(int i=1;i<=n*2;++i){
		cout << "? " << st.size()+1;
		for(auto id : st) cout << ' ' << id;
		cout << ' ' << i << endl;

		int res; cin >> res;
		if(res == 0){
			st.insert(i);
		}else{
			ans[i] = res;
		}
	}

	st.clear();
	vector<int> todo;
	for(int i=1;i<=2*n;++i) {
		if(ans[i]) st.insert(i);
		else todo.pb(i);
	}
	
	// 反查 n 次
	for(int i=1;i<=n;++i){
		int need = todo.back(); todo.pop_back();

		cout << "? " << st.size()+1;
		for(auto id : st) cout << ' ' << id;
		cout << ' ' << need << endl;

		int res; cin >> res;
		ans[need] = res;
	}

	cout << "! ";
	for(int i=1;i<=2*n;++i) cout << ans[i] << ' ';
	cout << endl;
}
posted on 2025-10-13 01:06  xiaowang524  阅读(77)  评论(2)    收藏  举报