Codeforces Round #418 (Div. 2)

来源:互联网 发布:mysql表结构导出word 编辑:程序博客网 时间:2024/06/05 23:11

A. An abandoned sentiment from past

题目大意:

输入n和m,表示有n个数的一个序列,有m个空缺,然后第二行输入n个数,第三行输入m个数,这n个数中,0表示空缺项,然后空缺的项从m个数的序列中选,最后填满这n个数的序列,并且要保证这个序列不是递增的数列,如果可以形成这个数列,就输出Yes,如果不可以输出No;

基本思路:

把m个数的序列中大的数尽可能放在前面的空缺位置上,然后如果还是不满足,那么肯定就不满足了。主要是想到先填再判断,我总是想一次完成,以后做题的时候也可以想一下先完成一部分任务,再完成一部分任务,最终完成任务;

代码如下:

#include<bits/stdc++.h>


using namespace std;


bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int a[210],b[210],n,m;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)
        scanf("%d",&b[i]);
    sort(b+1,b+m+1,cmp);
    int pos=1;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0)
            a[i]=b[pos++];
    }
    int ok=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]<a[i-1])
        {
            ok=1;
            break;
        }
    }
    if(ok) printf("Yes\n");
    else printf("No\n");
    return 0;
}


B. An express train to reveries

题目大意:

输入一个含有n个整数的序列a,再输入一个含有n个整数的序列b,然后保证能输出一个序列,该序列含有1~n这n个数,且该序列每一位和a的对应位,在n个位上只有一个不同,和b也保证如此,输出该序列;

基本思路:

要这样的话,必然a和b之间只能有一个或者两个或者没有对应位不同,然后就分类讨论好了;

代码如下:


#include<bits/stdc++.h>


using namespace std;


const int maxn = 1000+10;
int a[maxn],b[maxn],vis[maxn],c[maxn];


int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    memset(vis,0,sizeof(vis));
    memset(c,0,sizeof(c));
    int ok=0,x=0,xx=0,y=0,yy=0;
    for(int i=1;i<=n;i++)
        if(a[i]!=b[i])  ok++;
    if(ok==0)
    {
        for(int i=1;i<=n;i++)
        {
            if(a[i]==b[i]&&vis[a[i]]==0)
                c[i]=a[i],vis[a[i]]=1;
            else x=i;
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0) y=i;
        }
        c[x]=y;
    }
    else if(ok==1)
    {
        for(int i=1;i<=n;i++)
        {
            if(a[i]==b[i]) c[i]=a[i],vis[a[i]]=1;
            else x=i;
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0) y=i;
        }
        c[x]=y;
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if(a[i]==b[i]) c[i]=a[i],vis[a[i]]=1;
            else (x?xx:x)=i;
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0)
                (y?yy:y)=i;//这个写法学着写;
        }
        if(a[x]==y&&a[xx]!=yy&&b[x]!=y&&b[xx]==yy)
        {
            c[x]=y;
            c[xx]=yy;
        }
        else if(a[x]!=y&&a[xx]==yy&&b[x]==y&&b[xx]!=yy)
        {
            c[x]=y;
            c[xx]=yy;
        }
        else
        {
            c[xx]=y;
            c[x]=yy;
        }
    }
    for(int i=1;i<=n;i++)
        printf("%d ",c[i]);
    return 0;
}


C. An impassioned circulation of affection

题目大意:

输入一个整数n,然后输一个含有n个字符的字符串,然后,输入整数m,然后输入m对整数k和字符c,每输入一堆,输出把其中k位变为c后相连的c的最大长度;

基本思路:

方法一:

尺取法,适用于首先得是连续区间,然后啥时候用这个得自己体会,我也正处在摸索中;

方法二:

dp,用一个num[i][j]表示前i个字符中含有字符j的个数,一个dp[i][j]表示变i个字符为j所能形成的字符j的连续区间的长度,然后预处理一下就好了,很快;

法一:

#include<bits/stdc++.h>


using namespace std;


const int maxn = 2000+10;
char s[maxn];
int k,len;
char c;


int solve()
{
    int l=0,r=0,cnt=0,ans=0;
    while(l<len&&r<len)
    {
        while(r<len&&(s[r]==c||cnt<k))
        {
            if(s[r]!=c)
                cnt++;
            r++;
        }
        ans=max(ans,r-l);
        while(l<len&&s[l]==c)
            l++;
        l++;
        cnt--;
    }
    return ans;
}


int main()
{
    scanf("%d",&len);
    getchar();
    scanf("%s",s);
    int n;
    scanf("%d\n",&n);
    while(n--)
    {
        scanf(" %d %c",&k,&c);
        printf("%d\n",solve());
    }
    return 0;
}


法二:

#include<bits/stdc++.h>


using namespace std;


int num[2000][30],dp[2000][30],n;
char s[2000];


void solve(int x)
{
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            int z=num[j][x]-num[i-1][x];
            int d=j-i+1;
            dp[d-z][x]=max(dp[d-z][x],d);
        }
    }
    return;
}


int main()
{
    scanf("%d",&n);
    scanf("%s",s);
    memset(num,0,sizeof(num));
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<26;j++)
            num[i][j]=num[i-1][j];
        num[i][s[i-1]-'a']++;
    }
    memset(dp,0,sizeof(dp));
    for(int i=0;i<26;i++) solve(i);
    int m;
    scanf("%d",&m);
    while(m--)
    {
        int x;
        char c[5];
        scanf("%d%s",&x,c);
        x=min(x,n-num[n][c[0]-'a']);
        printf("%d\n",dp[x][c[0]-'a']);
    }
    return 0;
}

原创粉丝点击