Gym 101484 I Matrix Sum

来源:互联网 发布:网络代理可信吗 编辑:程序博客网 时间:2024/05/22 00:39

题意:题目给了一个矩阵 A 的定义:
Aij=Nk=1(Mik+Mkj)Mij
其中 M 是一个仅由 0 和 1 组成的矩阵
问,给定一个 nn(1n1e3)A 矩阵, 问满足上面等式的 M 矩阵有几个

分析: 这个题的关键就是从 A 矩阵中找出几个与 M 矩阵的等式关系。
我们用 RAi 表示 A 矩阵第 i 行的和,RMi表示M
CAi 表示 A 矩阵第 i 列的和,CMi表示M
totA 表示 A 矩阵的总和,totM 表示M 矩阵的总和

则原定义变成了: Aij=RMi+CMjMij

1.可以发现的是,每个 Mij 是使 A ij 列上的位置都+1,这样的话,每个 M 上的 1,都会在 A 上加 2n1 次。因此可以得到第一个等式:
totM(2n1)=totA
所以,如果 totA 不整除 2n1 ,答案为 0

2.对于每个 RAi 可以发现的是,整个 M 上的 1 都会在第 RAi 行上加 1 而且 Mi 行的 1 会加 n 次,由等式1 我们可以得到totM=totA/(2n1)
所以会得到第二个等式: RAi=totM+(n1)RMi
所以,如果RAitotM 不整除 n1 ,答案也是0.
对于每个CAi 也同理。由此,我们可以得到每个RMiCMi

3.如果上面两个都满足,那么我们回到题目给的等式,RMi , CMiAij 都是已知了,所以这样每个Mij 都能求出来,而且是唯一的。求出来之后判断一下是否为 01,是的话答案就是1,不是答案就是0.

4.还有一个特殊情况就是 n=1 的时候,直接特判一下即可。

以下是代码。

#include<bits/stdc++.h>using namespace std;#define ull unsigned long long#define ll long long#define lson l,mid,id<<1#define rson mid+1,r,id<<1|1typedef pair<int, int>pii;typedef pair<ll, ll>pll;typedef pair<double, double>pdd;const double eps = 1e-6;const int MAXN = 1005;const int MAXM = 100005;const ll LINF = 0x3f3f3f3f3f3f3f3f;const int INF = 0x3f3f3f3f;const double FINF = 1000000000000000.0;const ll MOD = 1000000007;const double PI = acos(-1);int f[MAXN][MAXN];int row[MAXN], col[MAXN];int main() {    memset(col, 0, sizeof(col));    memset(row, 0, sizeof(row));    int n, tot = 0; scanf("%d", &n);    for (int i = 1; i <= n; ++i) {        for (int j = 1; j <= n; ++j) {            scanf("%d", &f[i][j]);            row[i] += f[i][j];            col[j] += f[i][j];            tot += f[i][j];        }    }    if (n == 1) {        if (f[1][1] == 1 || f[1][1] == 0)goto ans_1;        else goto ans_0;    }    if (tot % (2 * n - 1) != 0)goto ans_0;    tot = tot / (2 * n - 1);    for (int i = 1; i <= n; ++i) {        if ((row[i] - tot) % (n - 1) || row[i] < tot)goto ans_0;        if ((col[i] - tot) % (n - 1) || col[i] < tot)goto ans_0;        row[i] = (row[i] - tot) / (n - 1);        col[i] = (col[i] - tot) / (n - 1);    }    for (int i = 1; i <= n; ++i) {        for (int j = 1; j <= n; ++j) {            int now = row[i] + col[j] - f[i][j];            if (now != 0 && now != 1)goto ans_0;        }    }    goto ans_1;ans_0:    printf("0\n");    return 0;ans_1:    printf("1\n");    return 0;}
原创粉丝点击