构造的时候把a0视为0
构造出可能有负数的序列a b 再构造出矩阵e e[i][j] = |a[i] + b[j] - w[i][j]|
若e都为0 则k取大于w中所有数字的值即可
若e[i][j]不为0 则k可取e[i][j] 若有e[i'][j']也不为0且e[i][j] != e[i'][j'] 则无解
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
#define abs(x) ((x) < 0 ? (-(x)) : (x))
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 100;
LL INF = 1;
LL w[MAXN+10][MAXN+10];
LL a[MAXN+10], b[MAXN+10], e[MAXN+10][MAXN+10];
int n, m;
int main()
{
for(int i = 1; i <= 18; i++) INF *= 10;
LL k = -1;
bool all0 = true, ok = true;
SF("%d%d", &n, &m);
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) cin >> w[i][j];
for(int i = 1; i <= m; i++) b[i] = w[1][i];
for(int i = 1; i <= n; i++) a[i] = w[i][1] - b[1];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
e[i][j] = abs(a[i] + b[j] - w[i][j]);
if(e[i][j]) all0 = false;
}
if(all0) k = INF;
else {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(e[i][j] != 0)
{
if(~k && k != e[i][j]) { ok = false; break; }
k = e[i][j];
}
}
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if(w[i][j] >= k) { ok = false; break; }
if(!ok) { PF("NO"); return 0; }
PF("YES\n"); cout << k << '\n';
for(int i = 1; i <= n; i++) while(a[i] < 0) a[i] += k;
for(int i = 1; i <= m; i++) while(b[i] < 0) b[i] += k;
cout << a[1]; for(int i = 2; i <= n; i++) cout << ' ' << a[i];
cout << '\n';
cout << b[1]; for(int i = 2; i <= m; i++) cout << ' ' << b[i];
}