Codeforces Round #627 (Div. 3)

Posted zjj0624

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #627 (Div. 3)相关的知识,希望对你有一定的参考价值。

B. Yet Another Palindrome Problem
题意
给你一个序列a,问你能不能找到一个大于等于3的子序列,使这个子序列是回文的。
思路
只要有三个相同的,就一定是YES,如果有两个相同的,就看这两个下标是否相邻,如果不相邻就YES,然后遍历数组来判断就可以了。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 2e5+10;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int a[5005];
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       int n;
       cin>>n;
       map<int,int>mp;
       bool flag=false;
       for(int i=1 ; i<=n ; i++)
       {
           cin>>a[i];
           mp[a[i]]++;
           if(mp[a[i]]>=3) flag=true;
       }
       if(flag)
       {
           cout<<"YES"<<endl;
           continue;
       }
       for(auto x:mp)
       {
           if(x.se>=2)
           {
               int j;
               for(int i=1 ; i<=n ; i++)
               {
                   if(a[i]==x.fi)
                   {
                       j=i;
                       break;
                   }
               }
               int sum=0;
               for(int i=j+1 ; j<=n ; j++)
               {
                   if(a[i]==x.fi) break;
                   sum++;
               }
               if(sum!=0) flag=true;
           }
       }
       if(flag) cout<<"YES"<<endl;
       else cout<<"NO"<<endl;
   }
   return 0;
}

C - Frog Jumps
题意
给你一个字符串,由L和R组成,R表示向右跳,可以跳1~d步,L表示向左跳,跟向右的范围一样,问是否可以跳到终点,求出最小的d。
思路
二分答案。
check数组判断是否会走死路,如果走死路就false,如果能走到尽头就是true,如果当前点是R的时候就跳d步,如果当前点是L的时候就每次只向左一步。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 2e5+10;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
string s;
bool check(int x)
{
   map<int,bool>mp;
   int ps=-1;
   mp[ps]=true;
   ps+=x;
   mp[ps]=true;
   while(ps<s.length())
   {
       if(s[ps]=='L') ps--;
       else ps+=x;
       if(mp[ps]) return false;
       mp[ps]=true;
   }
   return true;
}
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       cin>>s;
       int l=1,r=1e9;
       while(l<r)
       {
           int mid=l+r>>1;
           if(check(mid)) r=mid;
           else l=mid+1;
           //cout<<l<<" "<<r<<endl;
       }
       cout<<l<<endl;
   }
   return 0;
}

D - Pair of Topics
题意
给你一个序列a,和b,如果出现 i < j , a i + a j > b i + b j i<j,a_i+a_j>b_i+b_j i<j,ai+aj>bi+bj,我们就说这个pair是好的,问有多少组好的pair。
思路
对给的这个条件进行转换 a i − b i > b j − a j a_i-b_i>b_j-a_j aibi>bjaj,我们让第一个序列变成 a i − b i a_i-b_i aibi第二个序列变成 b j − a j b_j-a_j bjaj,然后我们就判断第一个序列的元素,在第二个序列中的大小关系,通过树状数组来维护就可以了。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 2e5+30;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int a[N*2],b[N*2],t[2*N],a1[N*2],b1[N*2],tr[N*2];
int lowbit(int x){return x&(-x);}
void add(int x,int c)
{
    for(int i=x ; i<=4e5+10 ; i+=lowbit(i)) tr[i]+=c;
}
int getsum(int x)
{
    int ans=0;
    for(int i=x ; i ; i-=lowbit(i)) ans+=tr[i];
    return ans;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1 ; i<=n ; i++) cin>>a[i];
    for(int i=1 ; i<=n ; i++) cin>>b[i];
    int cnt=0;
    for(int i=1 ; i<=n ; i++) a1[i]=a[i]-b[i],t[++cnt]=a1[i];
    for(int i=1 ; i<=n ; i++) b1[i]=b[i]-a[i],t[++cnt]=b1[i];
    sort(t+1,t+1+cnt);
    int m=unique(t+1,t+1+cnt)-t-1;
    for(int i=1 ; i<=n ; i++) a1[i]=lower_bound(t+1,t+1+m,a1[i])-t;
    for(int i=1 ; i<=n ; i++) b1[i]=lower_bound(t+1,t+1+m,b1[i])-t;
    for(int i=1 ; i<=n ; i++) add(b1[i],1);
    ll ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        add(b1[i],-1);
        ans+=getsum(a1[i]-1);
    }
    cout<<ans<<endl;
    return 0;
}

E - Sleeping Schedule
题意
给你一个序列a,你每次可以选择加 a i a_i ai或者 a i − 1 a_i-1 ai1,时间是从0开始,如果大于等于h,就对h取模,问有多少个时间在区间l,r内,求最大的数量.
思路
简单DP
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 2e5+30;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int a[2010],dp[2010][2010];
bool vis[2010][2010];
int main()
{
    int n,h,l,r;
    cin>>n>>h>>l>>r;
    for(int i=1 ; i<=n ; i++) cin>>a[i];
    vis[1][0]=true;
    int ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        for(int j=0 ; j<h ; j++)
        {
            if(vis[i][j])
            {
                if((j+a[i])%h>=l&&(j+a[i])%h<=r) dp[i+1][(j+a[i])%h]=max(dp[i][j]+1,dp[i+1][(j+a[i])%h]);
                else dp[i+1][(j+a[i])%h]=max(dp[i][j],dp[i+1][(j+a[i])%h]);
                if((j+a[i]-1)%h>=l&&(j+a[i]-1)%h<=r) dp[i+1][(j+a[i]-1)%h]=max(dp[i][j]+1,dp[i+1][(j+a[i]-1)%h]);
                else dp[i+1][(j+a[i]-1)%h]=max(dp[i][j以上是关于Codeforces Round #627 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #627 (Div. 3) 补题

Codeforces Round #627 (Div. 3)

Codeforces Round #627 (Div. 3)(A--D)

Codeforces Round #627 (Div. 3) D. Pair of Topics(二分/直接遍历)

Codeforces Round #627 (Div. 3)F. Maximum White Subtree

Codeforces Round #627 (Div. 3) F - Maximum White Subtree(深度优先搜索)