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;
}
时间: 2025-01-10 07:49:23

codeforces 509 D. Restoring Numbers(数学+构造)的相关文章

CodeForces 468A. 24 Game(数学构造)

题目链接:http://codeforces.com/problemset/problem/468/A A. 24 Game time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Little X used to play a card game called "24 Game", but recently he has f

codeforces 509D Restoring Numbers

codeforces 509D Restoring Numbers 题意: v[i][j]=(a[i]+b[j])%k 现在给出n*m矩阵v[][], 求a[],b[]和k, 任意一种情况都行. 限制: 1 <= n,m <= 100; 0 <= v[i][j] <= 100 思路: 对于数组a[], 无论怎么变, 数组之间的差始终不变, b[]也同理 利用这个求出k 再设a[0]=0,b[0]=0,求出剩下的东西.

codeforces 459C - Pashmak and Buses 【构造题】

题目:codeforces 459C - Pashmak and Buses 题意:给出n个人,然后k辆车,d天时间,然后每天让n个人选择坐一辆车去上学,要去d天不能有任意两个人乘同一辆车,不能的话输出 -1 分类:数学,构造 分析:这个题目首先得分析,我开始想到的是首先用相同的放在一起,比如 7 2 3 这样构造 1 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 2 2 2 1 1 1 就是需要的天数跟每一行出现次数最多的数的出现次数相等,但是发现还有更优

codeforces 848B - Rooter&#39;s Song(构造+几何)

原题链接:http://codeforces.com/problemset/problem/848/B 题意:好多个人分别从x,y轴不同位置不同时间往垂直坐标轴方向移动,一旦相遇他们转向,问所有人的到达边缘的位置. 思路:即使相遇后没有改变方向,终点位置还是不变的. 1.首先可以根据开始移动的时间将每个人的初始位置往后移动ti单位,这样就可以看作所有人都同时开始移动了. 2.接下来,假设两个人i,j在t时刻(x, y)处相撞,那么可以推知两个人的初始位置分别为(x-t, y),(x, y-t),

Codeforces 9C Hexadecimal&#39;s Numbers - 有技巧的枚举

2017-08-01 21:35:53 writer:pprp 集训第一天:作为第一道题来讲,说了两种算法, 第一种是跟二进制数联系起来进行分析: 第二种是用深度搜索来做,虽然接触过深度搜索但是这种题型还是我第一次见: 题目: 统计1~n之间有多少数字只由0,1构成 1 ≤ n ≤ 1e9 用深度搜索解决这种问题: 代码如下: #include <iostream> #include <map> using namespace std; map<int,int>vis;

[2016-04-14][codeforces][630][C][ Lucky Numbers]

时间:2016-04-14 23:12:27 星期四 题目编号:[2016-04-14][codeforces][630][C][ Lucky Numbers] 题目大意: 问n位数字以内的幸运数字有多少个 幸运数字:只含有7,8的数字 分析: 长度为i 的幸运数字,每一位有两种可能,7 , 8,那么长度为i的幸运数字总共有 $2^i$中可能 那么长度为n 以内的所有幸运数字 就是 $2^1 + 2^2 + - + 2^n$, #include<cstdio> using namespace

CodeForces 449C Jzzhu and Apples 数学+素数

这道题目晚上本来就花了很多把都××了,着实觉得自己思路没错啊,回顾一下思路,给你n个数,分成两两组合一对,分成最多组如何分,但是组合的两个数 不能互素,所以呢 偶数肯定是好的了,所以先放着,先把素数给搞定,10^5所以枚举所有包含该素数因子的数,如果刚好分组则最好,不然的话其中有偶数的踢掉一个给下面的偶数处理部分,最后再处理偶数的部分,这样肯定满足组数最多,完全没有问题,后来方法确实是没问题啊,只是代码有问题,我靠!真是脑残!,今天看到一位大牛的想法,我跟他是一样的,只是代码写搓了,后来改了又改

Codeforces 12E Start of the season 构造 一个n*n矩阵使得每行恰好有一个[0,n-1]且对称

题目链接:点击打开链接 题意: 给定一个n 构造 一个n*n矩阵使得每行恰好有一个[0,n-1]且关于主对角线对称 且主对角线必须全为0 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #inc

UVA12716 GCD XOR 数论数学构造

题目给你一个N,让你求 两个数字 A,B,且   A>=B<=N,是的 gcd(A,B) == A^B N的范围是 3*10^7大的吓人一开始没敢想构造,因为就算构造开的数组也太大了,已经10^7了,后来想了半天在^运算这里也没有想出来什么,所以没办法还是大胆构造吧,构造就去按照他题目的意思来了,构造两个数字 i,j其中j是i的倍数,那么j + i与i的最大公约数肯定是i了,那么(j+i)^i == i这样构造出来的就算满足了,然后再模仿gcd辗转相除的愿意  把它们放在一个数组里计数,这样预