[CF509D] Restoring Numbers && 构造

构造的时候把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];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值