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

题目链接:https://codeforces.com/problemset/problem/954/C
博客园食用链接: https://www.cnblogs.com/lonely-wind-/p/13450882.html

There is a matrix A of size x × y filled with integers. For every i [ 1 , x ] , j [ 1 , y ] i\in[1,x],j\in[1,y] , A i , j = y ( i 1 ) + j 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 a_1, a_2, ..., a_n denoting that you started in the cell containing the number a 1 a_1 , then moved to the cell with the number a 2 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 a_2 (in one step), then move to the cell containing a 3 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 ) 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 n integers a 1 , a 2 , . . . , a n ( 1 a i 1 0 9 ) 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 1 0 9 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 1 0 9 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 x*y 标号

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

接下来我们还需要检查的是相邻两个是1的情况,看看他们是否处于同一行,那么判断也很简单: ( a [ i ] 1 ) / l e n = = ( a [ i 1 ] 1 ) / l e n (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;
}

猜你喜欢

转载自blog.csdn.net/qq_43906000/article/details/107855257