首页 > 代码库 > codeforces 509 D. Restoring Numbers(数学+构造)

codeforces 509 D. Restoring Numbers(数学+构造)

题目链接:http://codeforces.com/problemset/problem/509/D

题意:题目给出公式w[i][j]= (a[i] + b[j])% k; 给出w,要求是否存在这样的数列,若存在则求出a,b 和k

 

题解:如果有符合条件的点的话那么a[i],b[j]可以任意转换比如说a[i],b[j]可以转化为a[i]-p,b[i]+p。所以只要存在

符合条件的解的a[i]可以为任意值。也就是说a[i]可以先赋值为0然后其他就都可以推出来了,当然开始推出后会发现

有负的,没事,还要模一个k,接下来就要验证是否存在k。

不妨设e[i][j]=abs(a[i]+b[j]-w[i][j])显然要使e[i][j]为0才能符合条件,所以要使e[i][j]%k=0。求一下所有e[i][j]

的gcd得出一个g。显然g就是k。如果g为0肯定存在而且k取最大值+1,否则,判断g是不是大于所有的w[i][j],如果是

那么k存在为最大值+1,不然不存在。

 

#include <iostream>#include <cstring>#include <cmath>using namespace std;typedef long long ll;const ll inf = 1e18;ll a[200] , b[200] , w[200][200] , e[200][200];ll gcd(ll x , ll y) {    return (y > 0) ? gcd(y , x % y) : x;}int main() {    int n , m;    cin >> n >> m;    for(int i = 0 ; i < n ; i++) {        for(int j = 0 ; j < m ; j++) {            cin >> w[i][j];        }    }    a[0] = 0;    for(int j = 0 ; j < m ; j++) {        b[j] = w[0][j] - a[0];    }    for(int j = 1 ; j < n ; j++) {        a[j] = w[j][0] - b[0];    }    ll gg = a[0] + b[0] - w[0][0];    for(int i = 0 ; i < n ; i++) {        for(int j = 0 ; j < m ; j++) {            e[i][j] = abs(a[i] + b[j] - w[i][j]);            gg = gcd(gg , e[i][j]);        }    }    ll k = 0;    if(gg == 0) {        for(int i = 0 ; i < n ; i++) {            for(int j = 0 ; j < m ; j++) {                k = max(k , w[i][j] + 1);            }        }        cout << "YES" << endl;        cout << k << endl;        for(int i = 0 ; i < n ; i++) {            if(a[i] < 0) {                cout << w[i][0] + k - b[0] << ‘ ‘;            }            else {                cout << a[i] << ‘ ‘;            }        }        cout << endl;        for(int i = 0 ; i < m ; i++) {            cout << b[i] << ‘ ‘;        }        cout << endl;    }    else {        int flag = 0;        for(int i = 0 ; i < n ; i++) {            for(int j = 0 ; j < m ; j++) {                if(gg <= w[i][j]) {                    flag = 1;                    break;                }            }        }        if(flag) {            cout << "NO" << endl;        }        else {            cout << "YES" << endl;            cout << gg << endl;            for(int i = 0 ; i < n ; i++) {                cout << w[i][0] + gg - b[0] << ‘ ‘;            }            cout << endl;            for(int i = 0 ; i < m ; i++) {                cout << b[i] << ‘ ‘;            }            cout << endl;        }    }    return 0;}

codeforces 509 D. Restoring Numbers(数学+构造)