Codeforces 954C- Matrix Walk(思维+构造)

题目链接:https://codeforces.com/problemset/problem/954/C
CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/107855257

There is a matrix A of size x × y filled with integers. For every \(i\in[1,x],j\in[1,y]\) , \(A_{i, j} = y(i - 1) + j\). Obviously, every integer from [1..xy] occurs exactly once in this matrix.

You have traversed some path in this matrix. Your path can be described as a sequence of visited cells \(a_1, a_2, ..., a_n\) denoting that you started in the cell containing the number \(a_1\), then moved to the cell with the number \(a_2\), and so on.

From the cell located in i-th line and j-th column (we denote this cell as (i, j)) you can move into one of the following cells:

1.(i + 1, j) — only if i < x;
2.(i, j + 1) — only if j < y;
3.(i - 1, j) — only if i > 1;
4.(i, j - 1) — only if j > 1.
Notice that making a move requires you to go to an adjacent cell. It is not allowed to stay in the same cell. You don't know x and y exactly, but you have to find any possible values for these numbers such that you could start in the cell containing the integer a 1, then move to the cell containing \(a_2\) (in one step), then move to the cell containing \(a _3\) (also in one step) and so on. Can you choose x and y so that they don't contradict with your sequence of moves?

Input
The first line contains one integer number \(n (1 ≤ n ≤ 200000)\) — the number of cells you visited on your path (if some cell is visited twice, then it's listed twice).

The second line contains \(n\) integers \(a_1, a _2, ..., a_ n (1 ≤ a _i ≤ 10^9)\) — the integers in the cells on your path.

Output
If all possible values of x and y such that \(1 ≤ x, y ≤ 10^9\) contradict with the information about your path, print NO.

Otherwise, print YES in the first line, and in the second line print the values x and y such that your path was possible with such number of lines and columns in the matrix. Remember that they must be positive integers not exceeding \(10^9\).

Examples
Input
8
1 2 3 6 9 8 5 2
Output
YES
3 3

Input
6
1 2 1 2 5 3
Output
NO

Input
2
1 10
Output
YES
4 9

Note
The matrix and the path on it in the first test looks like this:
https://vj.z180.cn/51d6378b93a1916c8a09390d66b9e6b2?v=1596345081
Also there exist multiple correct answers for both the first and the third examples.

题目大意:你需要构造一个矩阵的行数和列数来使得行走的方案合法,如果无法构造输出NO,否则输出YES,并输出行数和列数。行走的方案为上下左右,对于一个矩阵按1到\(x*y\)标号

emmm,现在看来还是挺简单的,我们需要先求出它的列数,那么就先for一遍,如果两个数的间隔不是1的话那么说明他们是上下走的,直接\(abs(a[i]-a[i-1])=len\)就可以得出其列数,不过若下一次的间隔不是\(1\)也不是\(len\)的话,那么就是不合法的,直接break,然后检查一下是否有相邻的两个一样。这样就得出了一个矩阵的固定列数。

接下来我们还需要检查的是相邻两个是1的情况,看看他们是否处于同一行,那么判断也很简单:\((a[i]-1)/len==(a[i-1]-1)/len\)

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

#define debug printf("debug\n")
const int mac=2e5+10;

int a[mac];

int main(int argc, char const *argv[])
{
	int n;
	scanf ("%d",&n);
	for (int i=1; i<=n; i++)
		scanf ("%d",&a[i]);
	int flag=0,len=1,mx=a[1];
	for (int i=2; i<=n; i++){
		if (a[i]==a[i-1]) {flag=1; break;}
		if (abs(a[i]-a[i-1])!=1) {
			if (len!=1 && abs(a[i]-a[i-1])!=len){flag=1; break;}
			len=abs(a[i]-a[i-1]);
		}
		mx=max(mx,a[i]);
	}
	if (flag) {printf("NO\n"); return 0;}
	if (len==1) {
		printf("YES\n");
		printf("%d %d\n",mx,len); return 0;
	}
	for (int i=2; i<=n; i++){
		if (abs(a[i]-a[i-1])==1 && (a[i]-1)/len!=(a[i-1]-1)/len) {
			flag=1; break;
		}
	}
	if (flag) {printf("NO\n"); return 0;}
	printf("YES\n");
	printf("%d %d\n",mx/len+1,len);
	return 0;
}
posted @ 2020-08-07 09:51  lonely_wind  阅读(209)  评论(0编辑  收藏  举报