Codeforces 888

这次CF不是很难,我这种弱鸡都能在半个小时内连A四道……不过E题没想到还有这种折半+状压枚举+二分的骚操作,后面就挂G了……

A.Local Extrema

题目链接:https://cn.vjudge.net/problem/CodeForces-888A

You are given an array a. Some element of this array ai is a local minimum iff it is strictly less than both of its neighbours (that is, ai < ai - 1 and ai < ai + 1). Also the element can be called local maximum iff it is strictly greater than its neighbours (that is, ai > ai - 1 and ai > ai + 1). Since a1 and an have only one neighbour each, they are neither local minima nor local maxima.

An element is called a local extremum iff it is either local maximum or local minimum. Your task is to calculate the number of local extrema in the given array.

Input

The first line contains one integer n (1 ≤ n ≤ 1000) — the number of elements in array a.

The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 1000) — the elements of array a.

Output

Print the number of local extrema in the given array.

Example

Input
3
1 2 3
Output
0
Input
4
1 5 2 5
Output
2

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,num[1005],cnt;
bool local_extremum(int a,int b,int c){return (a<b && b>c)||(a>b && b<c);}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&num[i]);
    cnt=0;
    for(int i=2;i<=n-1;i++)
    {
        if(local_extremum(num[i-1],num[i],num[i+1])) cnt++;
    }
    cout<<cnt<<endl;
}
View Code

B.Buggy Robot

题目链接:https://cn.vjudge.net/problem/CodeForces-888B

Ivan has a robot which is situated on an infinite grid. Initially the robot is standing in the starting cell (0, 0). The robot can process commands. There are four types of commands it can perform:

  • U — move from the cell (x, y) to (x, y + 1);
  • D — move from (x, y) to (x, y - 1);
  • L — move from (x, y) to (x - 1, y);
  • R — move from (x, y) to (x + 1, y).

Ivan entered a sequence of n commands, and the robot processed it. After this sequence the robot ended up in the starting cell (0, 0), but Ivan doubts that the sequence is such that after performing it correctly the robot ends up in the same cell. He thinks that some commands were ignored by robot. To acknowledge whether the robot is severely bugged, he needs to calculate the maximum possible number of commands that were performed correctly. Help Ivan to do the calculations!

Input

The first line contains one number n — the length of sequence of commands entered by Ivan (1 ≤ n ≤ 100).

The second line contains the sequence itself — a string consisting of n characters. Each character can be U, D, L or R.

Output

Print the maximum possible number of commands from the sequence the robot could perform to end up in the starting cell.

Example

Input
4
LDUR
Output
4
Input
5
RRRUU
Output
0
Input
6
LLRRRR
Output
4

题意:

机器人可以Up,Down,Left,Right四个方向移动一格;

现在给出一系列移动指令,因为规定了机器人肯定能在执行完这一系列指令后能回到原点,所以着一系列指令中必然有些是无效指令;

求最大有效指令是多少个;

题解:

一个U跟一个D抵消,一个L和一个R抵消,对它们计数一下在再计算一下即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,cnt[5];
char mov[105];
int main()
{
    cin>>n;
    scanf("%s",mov+1);
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=n;i++)
    {
        if(mov[i]=='U') cnt[1]++;
        else if(mov[i]=='D') cnt[2]++;
        else if(mov[i]=='L') cnt[3]++;
        else if(mov[i]=='R') cnt[4]++;
    }
    int ans=2*min(cnt[1],cnt[2])+2*min(cnt[3],cnt[4]);
    cout<<ans<<endl;
}
View Code

C.K-Dominant Character

题目链接:https://cn.vjudge.net/problem/CodeForces-888C

You are given a string s consisting of lowercase Latin letters. Character c is called k-dominant iff each substring of s with length at least k contains this character c.

You have to find minimum k such that there exists at least one k-dominant character.

Input

The first line contains string s consisting of lowercase Latin letters (1 ≤ |s| ≤ 100000).

Output

Print one number — the minimum value of k such that there exists at least one k-dominant character.

Example

Input
abacaba
Output
2
Input
zzzzz
Output
1
Input
abcde
Output
3

题意:

给定一个小写字母串s,对某个字母c,如果对于s的所有长度为k的子串,都含有c,就称字符c为k-Dominant;

对字符串中的所有字母,求其k,求其中最小的。

题解:

求出字符串s中某个字符c的前后差距的最大值,即k;

例如:abacaba中的字符a;

s[1]='a',与前面(位置为0)差距为1(1-0=0),与后面的a差距为2(3-1=2);

s[3]='a',与前面(位置为1)差距为2(3-1=2),与后面的a差距为2(5-3=2);

……

s[7]='a',与前面(位置为5)差距为2(7-5=2),与后面差距(len+1)为1(7+1-7=1);

所以字符a对应的k为2;

对字符串s中每个字符都算出k,取其中最小的即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int inte[30],last[30];
char str[100000+5];
int main()
{
    scanf("%s",str+1);
    int len=strlen(str+1);
    memset(inte,0,sizeof(inte));
    memset(last,0,sizeof(last));
    for(int i=1;i<=len;i++)
    {
        int id=str[i]-'a';
        inte[id]=max(inte[id],i-last[id]);
        last[id]=i;
    }
    for(int i=0;i<26;i++)
    {
        if(inte[i]==0) continue;
        inte[i]=max(inte[i],len+1-last[i]);
    }

    int ans=0x3f3f3f3f;
    for(int i=0;i<26;i++)
    {
        if(inte[i]==0) continue;
        ans=min(ans,inte[i]);
    }
    cout<<ans<<endl;
}
View Code

D.Almost Identity Permutations

题目链接:https://cn.vjudge.net/problem/CodeForces-888D

A permutation p of size n is an array such that every integer from 1 to n occurs exactly once in this array.

Let's call a permutation an almost identity permutation iff there exist at least n - k indices i (1 ≤ i ≤ n) such that pi = i.

Your task is to count the number of almost identity permutations for given numbers n and k.

Input

The first line contains two integers n and k (4 ≤ n ≤ 1000, 1 ≤ k ≤ 4).

Output

Print the number of almost identity permutations for given n and k.

Example

Input
4 1
Output
1
Input
4 2
Output
7
Input
5 3
Output
31
Input
5 4
Output
76

题意:

对于一个1~n的序列,给定一个k,如果它的全排列中某一个排列,它至少有n-k个pi=i,就称其为almost identity permutation;

求almost identity permutation数目。

题解:

观察到1<=k<=4,所以我们可以分而治之;

先比如求出 n-1个pi=i 的排列有几个,在求n-2的,直到n-k,在全部加起来即可;

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,k;
long long ans;
long long C[1001][1001];
void calc_Cmn()//求组合数
{
    for(int i=0;i<1001;i++)
    {
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
}
int main()
{
    calc_Cmn();
    cin>>n>>k;
    for(int i=n-1;i>=n-k;i--)
    {
        if(i==n-1) ans+=1;
        if(i==n-2) ans+=C[n][i];
        if(i==n-3) ans+=C[n][i]*2;
        if(i==n-4) ans+=C[n][i]*9;
    }
    cout<<ans<<endl;
}
View Code

E.Maximum Subsequence

题目链接:https://cn.vjudge.net/problem/CodeForces-888E

You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of indices b1, b2, ..., bk (1 ≤ b1 < b2 < ... < bk ≤ n) in such a way that the value of  is maximized. Chosen sequence can be empty.

Print the maximum possible value of .

Input

The first line contains two integers n and m (1 ≤ n ≤ 35, 1 ≤ m ≤ 109).

The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 109).

Output

Print the maximum possible value of .

Example

Input
4 4
5 2 4 1
Output
3
Input
3 20
199 41 299
Output
19

题解:

拆成两半,枚举前半部分的所有状态,算出sum,存起来,记为l_sum[];

枚举后半部分状态,每算出一个sum,去l_sum[]里二分查找能和它加起来最大的,又不会超过m-1的;

AC代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int n,mid;
ll num[40],MOD;
ll l_sum[131100]; int _size=0;

ll bisearch(ll limit)//在l_sum[]中查找小于等于limit的最大值
{
    //printf("limit is %lld
",limit);
    int l=0,r=_size-1,mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        //printf("now l=%d r=%d %lld
",l,r,l_sum[mid]);
        if(l_sum[mid]==limit) return limit;

        if(l_sum[mid]>limit) r=mid-1;
        else l=mid+1;
    }
    return l_sum[l-1];
}
int main()
{
    cin>>n>>MOD;
    mid=n/2;
    for(int i=1;i<=n;i++) cin>>num[i],num[i]%=MOD;

    for(int state=0;state<(1<<mid);state++)
    {
        ll sum=0;
        for(int cnt=1,sta=state;sta>0;cnt++)
        {
            sum+=(sta&1)*num[cnt];
            sta=(sta>>1);
        }
        l_sum[_size++]=sum%MOD;
    }
    sort(l_sum,l_sum+_size);
    _size=unique(l_sum,l_sum+_size)-l_sum;
    //for(int i=0;i<_size;i++) cout<<l_sum[i]<<endl;cout<<endl;

    ll ans=-1;
    for(int state=0;state<(1<<(n-mid));state++)
    {
        ll sum=0;
        for(int cnt=mid+1,sta=state;sta>0;cnt++)
        {
            sum+=(sta&1)*num[cnt];
            sta=(sta>>1);
        }
        sum%=MOD;
        ans=max(ans,sum+bisearch(MOD-1-sum));

        if(ans==MOD-1) break;
    }

    cout<<ans<<endl;
}
View Code
原文地址:https://www.cnblogs.com/dilthey/p/7827481.html