Restoring Numbers

  

D. Restoring Numbers

Vasya had two arrays consisting of non-negative integers: a of size n and b of size m. Vasya chose a positive integerk and created an n × m matrix v using the following formula:

Vasya wrote down matrix v on a piece of paper and put it in the table.

A year later Vasya was cleaning his table when he found a piece of paper containing an n × m matrix w. He remembered making a matrix one day by the rules given above but he was not sure if he had found the paper with the matrix v from those days. Your task is to find out if the matrix w that you‘ve found could have been obtained by following these rules and if it could, then for what numbers k, a1, a2, ..., an, b1, b2, ..., bm it is possible.

Input

The first line contains integers n and m (1 ≤ n, m ≤ 100), separated by a space — the number of rows and columns in the found matrix, respectively.

The i-th of the following lines contains numbers wi, 1, wi, 2, ..., wi, m (0 ≤ wi, j ≤ 109), separated by spaces — the elements of the i-th row of matrix w.

Output

If the matrix w could not have been obtained in the manner described above, print "NO" (without quotes) in the single line of output.

Otherwise, print four lines.

In the first line print "YES" (without quotes).

In the second line print an integer k (1 ≤ k ≤ 1018). Note that each element of table w should be in range between 0and k - 1 inclusively.

In the third line print n integers a1, a2, ..., an (0 ≤ ai ≤ 1018), separated by spaces.

In the fourth line print m integers b1, b2, ..., bm (0 ≤ bi ≤ 1018), separated by spaces.

有 a 数列 长度为n b 数列长度为m 都是非负整数, 然后 他们两个数组组成一个n*m的矩阵,然后 w[i][j]=(a[i]+b[j])%m;

最后给出了这个矩阵和n 和m 就数列 a 和 数列 b 还有m , 令 a[0]-p=0;

那么我们得到了一个数列 0,a[2]-p-x1k...a[n]-xnk-p-  ; b[1]+p-y1k...b[n]+p- yn k, 然后

再搞出一个矩阵 m[i][j] 然后在abs(a[i]+b[i]-w[i][j])=m[i][j] ;  当m中的每个元素都为0时 就可以知道w 中最大的那个+1就是答案了,还有就是有不为0的

可以将数列带进去看一下就发现 m[i][j]=x*k 这样求一次gcd就好了

#include <iostream>
#include <cstdio>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int maxn=105;
long long ma[maxn][maxn];
long long a[maxn],b[maxn];
long long e[maxn][maxn];
long long gcd(long long a, long long b){
    if(b==0) return a;
    else return gcd(b,a%b);
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2){
           for(int i=0; i<n; ++i)
             for(int j=0; j<m;  ++j)
              scanf("%I64d",&ma[i][j]);
           a[0]=0;
           long long K;
           for(int i=1; i<n; ++i)
             a[i]=ma[i][0]-ma[0][0];
           for(int i=0; i<m; ++i)
             b[i]=ma[0][i];
           for(int i=0; i<n; ++i)
             for(int j=0; j<m ; ++j)
               e[i][j]=abs(a[i]+b[j]-ma[i][j]);
           bool falg=false;
           for(int i=0; i<n; ++i)
             for(int j=0; j<m; ++j)
              if(e[i][j]!=0) falg=true;
           K=0;
           if(falg==false){
              for(int i=0; i<n; ++i)
                 for(int j=0; j<m; ++j)
                  K=max(K,ma[i][j]);
                  K++;
                  puts("YES");
              printf("%I64d\n",K);
              for(int i=0; i<n; ++i)
                 printf("%I64d%c",(a[i]%K+K)%K,i==n-1?‘\n‘:‘ ‘);

              for(int i=0; i<m; ++i)
                 printf("%I64d%c",(b[i]%K+K)%K,i==m-1?‘\n‘:‘ ‘);

           }else{
               K=0;
               bool finde=false;
              for(int i=0; i<n; ++i){
                 if(finde) break;
               for(int j=0; j<m; ++j){
                   if(e[i][j]!=0){
                        K=e[i][j];
                     finde=true ; break;
                   }
               }
              }
              for(int i=0; i<n; ++i)
              for(int j=0 ; j<m; ++j){
                  K=gcd(K,e[i][j]);
              }
              finde=true;
              for(int i=0; i<n; ++i)
                 for(int j=0; j<m; ++j)
                  if(ma[i][j]>=K) finde=false;
              if(finde==false){
                 puts("NO"); continue;
              }
                  puts("YES");
              printf("%I64d\n",K);
              for(int i=0; i<n; ++i)
                 printf("%I64d%c",(a[i]%K+K)%K,i==n-1?‘\n‘:‘ ‘);
              for(int i=0; i<m; ++i)
                 printf("%I64d%c",(b[i]%K+K)%K,i==m-1?‘\n‘:‘ ‘);
           }

    }
    return 0;
}

时间: 2024-08-25 09:24:00

Restoring Numbers的相关文章

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 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然后其他就都可以推出来了,当然开始推出后会发现 有负的,没事,

Codeforces Round #289

A Maximum in Table B Painting Pebbles C Sums of Digits D Restoring Numbers E Pretty Song F Progress Monitoring 总结 1. B题一开始有些马虎,没有读完题就开始做,结果理解错题意WA了一次(样例居然还是一次就过的-).以后要把题目读完再开始做.这种做法虽然在读题上花费的时间多了,但却节省了更多的做题时间,所以我认为这是很有必要的. 题解 A. Maximum in Table i=1 或

题解[CodeForces1154A]Restoring Three Numbers

Description Polycarp has guessed three positive integers \(a\), \(b\) and \(c\). He keeps these numbers in secret, but he writes down four numbers on a board in arbitrary order - their pairwise sums (three numbers) and sum of all three numbers (one n

F - Restoring Table(按位与,按位或)

这题坑爹..按位没学好.&是同为1,结果才是1,而|是同为0,结果才是0,这样num1&num2,num1&num3,num1&num4,得到的结果里的二进制含有1的位数,则在原数num1和num2.3.4里肯定是1,含有0的位数,要么在原数中是0,要么在num2.3.4中是0,或者都是0 所以用|运算,把有1的位数(原数中肯定此位是1)都先还原回去,然后多次操作叠加起来.就能还原出一组可能的数据了(注意:只是可能的一组数据,因为会有多组解,无法都找到) F - Resto

Codeforces 490E. Restoring Increasing Sequence 二分

统计有几个'?',然后二分检测取满足条件的最小的数就可以了. 注意没有问号的时候也要检测一下.... E. Restoring Increasing Sequence time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Peter wrote on the board a strictly increasing sequence o

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

421. Maximum XOR of Two Numbers in an Array

Given a non-empty array of numbers, a0, a1, a2, - , an-1, where 0 ≤ ai < 231. Find the maximum result of ai XOR aj, where 0 ≤ i, j < n. Could you do this in O(n) runtime? Example: Input: [3, 10, 5, 25, 2, 8] Output: 28 Explanation: The maximum resul