一分求助,改了必关
查看原帖
一分求助,改了必关
1559405
YKCCFDW楼主2025/2/6 21:26
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

typedef long long ll;
const int MAXN = 2005;
const ll INF = (1LL << 63);

ll A[MAXN], B[MAXN];
ll a[MAXN * MAXN];
int p[MAXN * MAXN], q[MAXN * MAXN];
int n, m;

// 检查当前解是否满足所有条件
bool check() {
	// 检查第一种方程(行和)
	for (int i = 1; i <= n; ++i) {
		ll rowSum = 0;
		for (int j = 1; j <= n; ++j) {
			rowSum += a[(i - 1) * n + j];
		}
		if (rowSum != A[i]) return false;
	}
	// 检查第二种方程(列和)
	for (int j = 1; j <= n; ++j) {
		ll colSum = 0;
		for (int i = 1; i <= n; ++i) {
			colSum += a[(i - 1) * n + j];
		}
		if (colSum != B[j]) return false;
	}
	// 检查限制条件
	for (int i = 0; i < m; ++i) {
		if (a[p[i]] != q[i]) return false;
	}
	return true;
}

// 尝试求解
bool solve() {
	// 初始化所有未知数为 0
	memset(a, 0, sizeof(a));
	// 应用限制条件
	for (int i = 0; i < m; ++i) {
		a[p[i]] = q[i];
	}
	// 先处理行和
	for (int i = 1; i <= n; ++i) {
		ll rowSum = 0;
		for (int j = 1; j <= n; ++j) {
			rowSum += a[(i - 1) * n + j];
		}
		int firstFree = -1;
		for (int j = 1; j <= n; ++j) {
			int idx = (i - 1) * n + j;
			bool isRestricted = false;
			for (int k = 0; k < m; ++k) {
				if (p[k] == idx) {
					isRestricted = true;
					break;
				}
			}
			if (!isRestricted) {
				if (firstFree == -1) firstFree = idx;
			}
		}
		if (firstFree != -1) {
			a[firstFree] += A[i] - rowSum;
		} else {
			if (rowSum != A[i]) return false;
		}
	}
	// 再处理列和
	for (int j = 1; j <= n; ++j) {
		ll colSum = 0;
		for (int i = 1; i <= n; ++i) {
			colSum += a[(i - 1) * n + j];
		}
		int firstFree = -1;
		for (int i = 1; i <= n; ++i) {
			int idx = (i - 1) * n + j;
			bool isRestricted = false;
			for (int k = 0; k < m; ++k) {
				if (p[k] == idx) {
					isRestricted = true;
					break;
				}
			}
			if (!isRestricted) {
				if (firstFree == -1) firstFree = idx;
			}
		}
		if (firstFree != -1) {
			a[firstFree] += B[j] - colSum;
		} else {
			if (colSum != B[j]) return false;
		}
	}
	return check();
}

int main() {
	int T;
	cin >> T;
	while (T--) {
		cin >> n >> m;
		// 读取行和条件
		for (int i = 1; i <= n; ++i) {
			cin >> A[i];
		}
		// 读取列和条件
		for (int i = 1; i <= n; ++i) {
			cin >> B[i];
		}
		// 读取限制条件
		for (int i = 0; i < m; ++i) {
			cin >> p[i] >> q[i];
		}
		if (solve()) {
			cout << "OK" << endl;
			for (int i = 1; i <= n * n; ++i) {
				cout << a[i];
				if (i < n * n) cout << " ";
			}
			cout << endl;
		} else {
			cout << "No Solution" << endl;
		}
	}
	return 0;
}
2025/2/6 21:26
加载中...