codeforces 954C

codeforces 954C

C. Matrix Walk

introduction

一个xy列矩形的矩形,每个格子的从左到右,从上到下编号。然后给出一条路径,确定xy的值,使得这条路径成立。

method

容易观察到,行数可以取一个最大值,如1e9
然后,当两个数的差大于1的时候,差就是列数(但是这只是必要,并不充分,还要检验)
这道题的思路就是先确定列数,然后检验是否符合要求。
需要检验以下几点:

  • 是否有两个连续相等的数
  • 是否有两个数的差大于1但不等于列数
  • 是否有从末尾到下一行的开头

这几点都是不符合要求的。

tips

构造比较难,但是验证比较容易

Q&A

Q1:为什么yy的默认值是1e9(我刚开始设置的是-1)?
A1:因为求列数的时候,得到的列数是大于1的,这样就无法处理列数等于1的情况。列数为1的情况,就是连续的情况,行数最大跟这种情况是一样的。

conclusion

做题目的时候关键点都有想到,可是没有将这些关键点正确的用程序表达出来。试图在输入的时候直接将答案构造出来,这样的做法比较困难。而先求一个必要条件,然后验证充分性,这样可以降低构造的难度。

reference

http://codeforces.com/blog/entry/58519

code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<istream>
#include<cassert>
#include<set>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
using namespace std;
typedef long long ll;
const int MAXN=2e5+10;
int arr[MAXN];
int main()
{
//    freopen("in.txt","r",stdin);
///构造比较难,但是验证比较容易
    bool ok=true;
    int aa,n,pre;
    scanf("%d",&n);
    int xx=1e9,yy=1e9;
    for(int ii=0;ii<n ;ii++ ){
        scanf("%d",&aa);
        arr[ii]=aa;
        if(ii==0)pre=aa;
        else {
            int stp=abs(pre-aa);
            if(stp>1)yy=stp;
            pre=aa;
        }
    }
    for(int ii=1;ii<n ;ii++ ){
        if(arr[ii-1]%yy==0&&arr[ii]==arr[ii-1]+1
           ||arr[ii]%yy==0&&arr[ii-1]==arr[ii]+1
           ||arr[ii]==arr[ii-1]
           ||abs(arr[ii]-arr[ii-1])>1&&abs(arr[ii]-arr[ii-1])!=yy)
           ok=false;
    }
    if(ok){
        printf("%s
%d %d","YES",xx,yy);
    }
    else printf("%s
","NO");
}
原文地址:https://www.cnblogs.com/MalcolmMeng/p/10224368.html