令人困惑的问题。
查看原帖
令人困惑的问题。
340803
InoueTakina楼主2023/10/26 12:24

如下代码不能通过测试点 #19,原因是 Wrong anwser.

// Stop the noise and stop the clocks
// Problem: P9721 [EC Final 2022] Inversion
// Contest: Luogu
#include<bits/stdc++.h>
using namespace std;
const int N = 2007;

int n, f[N][N], vis[N][N], a[N], p[N];

int ask (int l, int r) {
	// assert (l <= r);
	
	// assert (l <= n and r <= n and l > 0 and r > 0);
	
	if (vis[l][r]) return f[l][r];
	
	cout << "? " << l << " " << r << endl;
	cin >> f[l][r]; vis[l][r] = 1;
	cout << endl;
	return f[l][r];
}

int query (int x, int y) {
	if (x + 1 == y) return ask (x, y);
	else return ask (x, y) ^ ask (x + 1, y) ^ ask (x, y - 1) ^ ask (x + 1, y - 1);
}

int main () {
	cin >> n;
	for (int i = 1; i <= n; i ++) a[i] = i, vis[i][i] = 1;
	
	for (int i = 2; i <= n; i ++) {
		int l = 1, r = i - 1, pos = i;
		
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (query (a[mid], a[i])) pos = mid, r = mid - 1;
			else l = mid + 1;
		}
		
		for (int j = i; j > pos; j --) a[j] = a[j - 1];
		a[pos] = i;
		
		assert (pos > 0 and pos <= i);
				
		for (int j = 1; j <= i; j ++) p[a[j]] = j;
		
		if (i == n) for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
		
		for (int j = i - 1, res = 0; j; j --) {
			res ^= (p[j] > p[i]);
			f[j][i] = f[j][i - 1] ^ res;
			vis[j][i] = 1;
		}
		
		if (i == n) for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
		if (i == n) {
			cout << "! ";
			for (int j = 1; j <= n; j ++) p[a[j]] = j;
			for (int j = 1; j <= n; j ++) cout << p[j] << " ";
			break;
			exit (0);
		}
	}
	
	// for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
	
	
	
	cout << endl;
}

而如下代码可以通过。

#include<bits/stdc++.h>
using namespace std;
const int N = 2007;

int n, f[N][N], vis[N][N], a[N], p[N];

int ask (int l, int r) {
	// assert (l <= r);
	
	// assert (l <= n and r <= n and l > 0 and r > 0);
	
	if (vis[l][r]) return f[l][r];
	
	cout << "? " << l << " " << r << endl;
	cin >> f[l][r]; vis[l][r] = 1;
	
	return f[l][r];
}

int query (int x, int y) {
	if (x + 1 == y) return ask (x, y);
	else return ask (x, y) ^ ask (x + 1, y) ^ ask (x, y - 1) ^ ask (x + 1, y - 1);
}

int main () {
	cin >> n;
	for (int i = 1; i <= n; i ++) a[i] = i, vis[i][i] = 1;
	
	for (int i = 2; i <= n; i ++) {
		int l = 1, r = i - 1, pos = i;
		
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (query (a[mid], a[i])) pos = mid, r = mid - 1;
			else l = mid + 1;
		}
		
		for (int j = i; j > pos; j --) a[j] = a[j - 1];
		a[pos] = i;
		
		assert (pos > 0 and pos <= i);
		
		for (int j = 1; j <= i; j ++) p[a[j]] = j;
		
		for (int j = i - 1, res = 0; j; j --) {
			res ^= (p[j] > p[i]);
			f[j][i] = f[j][i - 1] ^ res;
			vis[j][i] = 1;
		}
	}
	
	for (int j = 1; j <= n; j ++) p[a[j]] = j;
	
	cout << "! ";
	
	for (int i = 1; i <= n; i ++) cout << p[i] << " ";
	
	cout << endl;
}

可是,下面这份代码并不会通过,理由是 Wa:

#include<bits/stdc++.h>
using namespace std;
const int N = 2007;

int n, f[N][N], vis[N][N], a[N], p[N];

int ask (int l, int r) {
	// assert (l <= r);
	
	// assert (l <= n and r <= n and l > 0 and r > 0);
	
	if (vis[l][r]) return f[l][r];
	
	cout << "? " << l << " " << r << endl;
	cin >> f[l][r]; vis[l][r] = 1;
	
	return f[l][r];
}

int query (int x, int y) {
	if (x + 1 == y) return ask (x, y);
	else return ask (x, y) ^ ask (x + 1, y) ^ ask (x, y - 1) ^ ask (x + 1, y - 1);
}

int main () {
	cin >> n;
	for (int i = 1; i <= n; i ++) a[i] = i, vis[i][i] = 1;
	
	for (int i = 2; i <= n; i ++) {
		int l = 1, r = i - 1, pos = i;
		
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (query (a[mid], a[i])) pos = mid, r = mid - 1;
			else l = mid + 1;
		}
		
		for (int j = i; j > pos; j --) a[j] = a[j - 1];
		a[pos] = i;
		
		assert (pos > 0 and pos <= i);
		
		for (int j = 1; j <= i; j ++) p[a[j]] = j;
		
		for (int j = i - 1, res = 0; j; j --) {
			res ^= (p[j] > p[i]);
			f[j][i] = f[j][i - 1] ^ res;
			vis[j][i] = 1;
		}
	}
		
	cout << "! ";
	
	for (int i = 1; i <= n; i ++) cout << p[i] << " ";
	
	cout << endl;
}

这份代码返回了 RE,原因是最后的 assert:

// Stop the noise and stop the clocks
// Problem: P9721 [EC Final 2022] Inversion
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P9721
// Time: 2023-10-26 11:53:02
// Memory Limit: 1 MB
// Author: Cocoly1990
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int N = 2007;

int n, f[N][N], vis[N][N], a[N], p[N];

int ask (int l, int r) {
	// assert (l <= r);
	
	// assert (l <= n and r <= n and l > 0 and r > 0);
	
	if (vis[l][r]) return f[l][r];
	
	cout << "? " << l << " " << r << endl;
	cin >> f[l][r]; vis[l][r] = 1;
	cout << endl;
	return f[l][r];
}

int query (int x, int y) {
	if (x + 1 == y) return ask (x, y);
	else return ask (x, y) ^ ask (x + 1, y) ^ ask (x, y - 1) ^ ask (x + 1, y - 1);
}

int main () {
	cin >> n;
	for (int i = 1; i <= n; i ++) a[i] = i, vis[i][i] = 1;
	
	for (int i = 2; i <= n; i ++) {
		int l = 1, r = i - 1, pos = i;
		
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (query (a[mid], a[i])) pos = mid, r = mid - 1;
			else l = mid + 1;
		}
		
		for (int j = i; j > pos; j --) a[j] = a[j - 1];
		a[pos] = i;
		
		assert (pos > 0 and pos <= i);
				
		for (int j = 1; j <= i; j ++) p[a[j]] = j;
		
		if (i == n) for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
		
		for (int j = i - 1, res = 0; j; j --) {
			res ^= (p[j] > p[i]);
			f[j][i] = f[j][i - 1] ^ res;
			vis[j][i] = 1;
		}
		
		if (i == n) for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
	}
	
	for (int j = 1; j <= n; j ++) assert (p[a[j]] == j);
	cout << "! ";
	for (int j = 1; j <= n; j ++) p[a[j]] = j;
	for (int j = 1; j <= n; j ++) cout << p[j] << " ";
	cout << endl;
}

四份代码仅仅在最后的输出有差别。

非常让人困惑的是,我仅仅是在最后重新更新了一遍排名数组,就可以通过测试点,但我在循环到 nn 时对排名数组进行了一次 assert,他通过了这次 assert,并且在此之后没有任何针对排名数组的操作。

真的无比令人困惑。

2023/10/26 12:24
加载中...