cf Educational Codeforces Round 40 C. Matrix Walk

原题:

C. Matrix Walk
time limit per test1 second
memory limit per test256 megabytes

inputstandard input
outputstandard output

There is a matrix A of size x × y filled with integers. For every , Ai, 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 a1, a2, …, an denoting that you started in the cell containing the number a1, then moved to the cell with the number a2, 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:

(i + 1, j) — only if i < x;
(i, j + 1) — only if j < y;
(i - 1, j) — only if i > 1;
(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 a1, then move to the cell containing a2 (in one step), then move to the cell containing a3 (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 a1, a2, …, an (1 ≤ ai ≤ 109) — the integers in the cells on your path.

Output
If all possible values of x and y such that 1 ≤ x, y ≤ 109 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 109.

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

中文:
给你一个序列,x1,x2,x3…xn,让你找出一个X×Y的二维矩阵,这个二维矩阵的排列方式是1到X×Y的数字横向依次排列。
在这个矩阵当中,你可以从一个位置(i,j)向上、向下、向左、向右移动,在不超过边界的情况下,按照这个移动方式,能否找到实现最开始给定序列的一个路径(不允许在同一个位置停留)。如果存在这个矩阵,输出这个矩阵的行数和列数,否则输出NO

例如样例1
这里写图片描述

代码:

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

const ll row=1e9;
int n,a[200001],r,l,x;


int main()
{
    ios::sync_with_stdio(false);

    while(cin>>n)
    {
        int flag=1,col=-1;
        r=0,l=0,x=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            if(i>1)
            {
                if(a[i-1]==a[i])//序列相邻值不能相同
                {
                    flag=0;
                    break;
                }
                if(abs(a[i]-a[i-1])>1)//差大于1,获得列数
                {
                    if(col==-1)
                        col=abs(a[i]-a[i-1]);
                    else
                    {
                        if(col!=abs(a[i]-a[i-1]))//出现了不同的列数,结果是NO
                        {
                            flag=0;
                        }
                    }
                }
                else
                {
                    if(a[i]>a[i-1])//判断矩阵,横向左右两侧分别距离x1的距离
                        x++;
                    if(a[i]<a[i-1])
                        x--;
                    r=max(r,x);
                    if(x<0)
                        l=max(l,abs(x));
                }
            }
        }
        //cout<<flag<<endl;
        if(flag)
        {
            if(col==-1)
            {
                col=row;
            }
            else
            {
                //cout<<col<<endl;
                int h=a[1]%col;
                if(h==0)
                    h=col;

                if(h-1<l||r+h>col)
                    flag=0;


                //cout<<l<<" "<<r<<endl;
                if(!flag)
                {
                    cout<<"NO"<<endl;
                }
            }
            if(flag)
            {
                cout<<"YES"<<endl;
                cout<<row<<" "<<col<<endl;
            }
        }
        else
            cout<<"NO"<<endl;
    }

    return 0;
}

思路:

比较恶心的模拟题

由于矩阵的排列方式可以知道,任意行相邻的两个位置的数字例如(i,j)和(i+1,j)之间的差一定是一个固定值col,也就是这个矩阵的列数。(如果矩阵只有一行例外)
由于矩阵当中移动的规则只能值在相邻的四个方向上面移动,同一行,向左或者向右移动,那么相邻的元素相差1;同一列,相邻元素差的是是列数col。以样例那个图片为例,同一行1,2,3 相邻的差1,这很明显。同一列,相邻的差3,也很明显。

那么,给定的序列x1,x2,x3…xn,如果不是全都在同一行,也就是相邻元素的差全是1,那么,如果有 xi x i xi+1 x i + 1 之间相差大于1,那么一定就是这个矩阵的列数。还可以知道,如果在这个序列当中出现了两个不一样的列数,那结果肯定是NO。

另外,因为给定的矩阵格式是固定的。如果给出的数据x1,x2,x3…xn满足列数和行数之间的安排,但是会出现以下两种情况,第一种, xi x i xi+1 x i + 1 之间跨度太大,例如序列[1,2,3,4,1],很明显走到4以后是不能走到1的。

第二种,给定的序列超出列数,例如序列[10,13,14,17,16,15],可以看出列数是3,但是从1一直到17画出完整的矩阵就可以知道,15这个元素是不能出现在16的左侧的。因为,列数是3,所以元素10上面的元素分别是7,4,1,也就是10应该在第一列,然而15却出现在了10的左侧。

注意到上面的两个问题,用模拟判断的方式就能解决。

至于输出的行数,直接输出数据范围的最大值即可,行数不影响结果的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值