码迷,mamicode.com
首页 > 其他好文 > 详细

AtCoder AGC037E Reversing and Concatenating

时间:2019-08-20 20:39:40      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:时间复杂度   aac   细节   tin   ons   题目   cpp   and   span   

题目链接

https://atcoder.jp/contests/agc037/tasks/agc037_e

题解

天哪,这场题目难度大概真的是乱序吧。。。。A<C<E<D<B<F? 后悔考场上没看看这题= =
首先在一般情况下,不妨设串中出现过的最小字符为\(a\), 最长连续的\(a\)的长度是\(l\), 那么显然答案的前至少\(2^{k-1}\times l\)位都是\(a\).
然后发现,假设确定了第一步的操作,那么后面的操作都是唯一确定的,且可以在\(O(n)\)时间内得到。
于是枚举一下第一步操作
然后。。就做完了啊。。。
时间复杂度\(O(N^2)\).

但是有个比较恶心的细节:如果这个字符串末尾有若干个字符\(a\)要特殊处理(具体见代码)。并且即便末尾\(a\)的长度不足\(l\)也有可能成为最优解(因为相当于省去了一次操作,应该是达到\(\frac{l}{2}\)就有可能)。
例如以下数据:

8 1
baaacbaa

因此WA了4发。

代码

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;

void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

const int N = 5000;
char a[N+3];
char ans[N+3][N+3];
char mnc;
int n,m,num;

bool cmp(int x,int y)
{
    for(int i=1; i<=n; i++)
    {
        if(ans[x][i]<ans[y][i]) return true;
        if(ans[x][i]>ans[y][i]) return false;
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    scanf("%s",a+1);
    mnc = 'z'; for(int i=1; i<=n; i++) mnc = min(mnc,a[i]);
    if(m>=14) {for(int i=1; i<=n; i++) printf("%c",mnc); return 0;}
    int len = 0,mxl = 0;
    for(int i=1; i<=n; i++)
    {
        if(a[i]!=mnc) len = 0;
        else len++;
        if(len>mxl) {mxl = len;}
    }
    len = 0; num = 0;
    for(int i=1; i<=n; i++)
    {
        if(a[i]!=mnc) len = 0;
        else len++;
        if(i==n)
        {
            num++;
            int tmp = min(n,len*(1<<m));
            for(int j=1; j<=tmp; j++) ans[num][j] = mnc;
            for(int j=tmp+1,k=n-len; j<=n; j++,k--) ans[num][j] = a[k];
        }
        if(len==mxl)
        {
            num++;
            int tmp = min(n,len*(1<<m-1));
            for(int j=1; j<=tmp; j++) ans[num][j] = mnc;
            for(int j=tmp+1,k=i+1; j<=n; j++,k++)
            {
                ans[num][j] = a[k<=n?k:2*n+1-k];
            }
        }
    }
//  for(int i=1; i<=num; i++) {for(int j=1; j<=n; j++) printf("%c",ans[i][j]); puts("");}
    int fans = 1;
    for(int i=1; i<=num; i++)
    {
        if(cmp(i,fans))
        {
            fans = i;
        }
    }
    for(int j=1; j<=n; j++) printf("%c",ans[fans][j]); puts("");
    return 0;
}

AtCoder AGC037E Reversing and Concatenating

标签:时间复杂度   aac   细节   tin   ons   题目   cpp   and   span   

原文地址:https://www.cnblogs.com/suncongbo/p/11385281.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!