zoukankan      html  css  js  c++  java
  • AtCoder AGC037E Reversing and Concatenating

    题目链接

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

    题解

    天哪,这场题目难度大概真的是乱序吧。。。。A<C<E<D<B<F? 后悔考场上没看看这题= =
    首先在一般情况下,不妨设串中出现过的最小字符为(a), 最长连续的(a)的长度是(l), 那么显然答案的前至少(2^{k-1} imes 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;
    }
    
  • 相关阅读:
    4.8 C++ typeid操作符
    4.7 C++ dynamic_cast操作符
    tomcat中class和jar的加载顺序(转)
    java Files类和Paths类的用法 (转)
    搭建DUBBO项目解决DUBBO.XML标签报错的问题(转载)
    Maven异常:Could not find artifact
    在docker宿主机上查找指定容器内运行的所有进程的PID
    jmap、jstack、jps无法连接jvm解决办法
    linux中如何查看某一进程的启动时间
    Eureka与ZooKeeper 的比较(转)
  • 原文地址:https://www.cnblogs.com/suncongbo/p/11385281.html
Copyright © 2011-2022 走看看