CF1851C 题解

题意:

Vlad记得他有一系列 n 个瓷砖和一个数字 k。
瓷砖从左到右编号,第 i 个瓷砖的颜色为 ci。

如果你站在第一块瓷砖上,开始向右跳任意数量的瓷砖,
你可以得到一条长度为 p 的路径,
路径的长度就是你经过瓷砖的数量。

弗拉德想看看是否有可能得到一条长度为 p 的路径,使得:

1.它在索引为n的瓦片处结束;p能被k整除;
2.路径被分成长度正好为k的块;
3.每个区块中的瓷砖具有相同的颜色,相邻区块中的颜色不一定不同。

写到一半写不下去了,于是用的机翻。

考虑最短路径怎么走:显然是 $ c_1 $ 为一个长度为 $ k $ 的区间左端点,$ c_n $ 为一个长度为 $ k $ 的区间的右端点,最短路径只有这一个或两个区间(因为有 $ c_1 = c_n $ 的情况)。

直接判定最短路径是否存在即可,因为如果最短的路径不存在,长的路径更不可能存在。

代码:

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

ll read(){
    char ch=getchar();
    ll s=0, w=1;
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w; 
}

ll n, k;
ll c[MAXN];

int main(){
    ll T = read();

    while(T--){
        n = read(), k = read();
        for(ll i = 1; i <= n; i++){
            c[i] = read();
        }

        ll cnt1 = 0, pos = 0;

        bool f1 = false, f2 = false;

        for(ll i = 1; i <= n; i++){
            if(c[i] == c[1]){
                cnt1++;
                pos = i;
                if(cnt1 == k){
                    f1 = true;
                    break;
                }
            }
        }

        if(c[1] == c[n] && f1){
            cout << "YES\n";
            continue;
        }

        ll cnt2 = 0;
        for(ll i = n; i >= pos; i--){
            if(c[i] == c[n]){
                cnt2++;
                if(cnt2 == k){
                    f2 = true;
                    break;
                }
            }
        }

        cout << (f1 && f2 ? "YES" : "NO") << endl;
    }
    return 0;
}
posted @ 2023-07-28 09:00  象征阳光  阅读(7)  评论(0)    收藏  举报  来源