因为是正整数解所以不能高斯消元了。
然后一开始想的是枚举a【1】,然后想办法O(n)检查,但是这个O(n)检查就是想不出来。
然后二分复杂度确实满足,但是感觉上不满足二分性。
在一段仔细思考之后,发现,a[1]的大小会控制其他值的大小,那就可以在check之中满足二分性。
然后就可以二分了。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1005; const int M = 2e3 + 5; const LL Mod = 2147483647; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; int n,s[N][N],ans,a[N]; int check(int x) { a[1] = x; for(int i = 2;i <= n;++i) { a[i] = s[1][i] - a[1]; if(a[i] <= 0) return 1; } for(int i = 2;i <= n;++i) { for(int j = i + 1;j <= n;++j) { if(a[i] + a[j] > s[i][j]) return 2; if(a[i] + a[j] < s[i][j]) return 1; } } return 0; } int main() { n = read(); int mx = 0; for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) { s[i][j] = read(); if(i == 1) mx = max(mx,s[i][j]); } int L = 1,r = mx - 1; while(L <= r) { int mid = (L + r) >> 1; if(check(mid) == 1) r = mid - 1; if(check(mid) == 2) L = mid + 1; if(check(mid) == 0) { ans = mid; break; } } printf("%d ",ans); for(int i = 2;i <= n;++i) printf("%d%c",s[1][i] - ans,i == n ? ' ' : ' '); system("pause"); return 0; } /* 4 5 2 1 4 0 9 6 5 9 0 7 6 6 7 0 3 5 6 3 0 */