CodeForces - 1316B String Modification(找规律)

题目链接:点击查看

题目大意:给出一个字符串 s ,需要求出一个 k ,满足 i ∈ [ 1 , n - k + 1 ]中,每个s[ i : i + k - 1 ]都反转一遍,使得最后得到的字符串字典序最小,若有多个 k 满足条件,求出最小的那个 k 

题目分析:读完题后最暴力的方法是 n * n * n ,显然是不行的,考虑是否有规律可循,自己手动模拟了一下发现确实有规律,但是比赛的时候没有发现奇偶又别,于是很可惜的被rj掉了,难过

自己拿着abcd和abcde试试就知道规律了:以 k = 3 为例:

abcd -> Cbad -> CD|AB

abcde -> Cbade -> CDabe -> CDE|BA

在最后结果那个部分我加了一个断点,很显然最后的结果由两部分组成:

  1. 前半部分:s[ k : len ]
  2. 后半部分:
    1. 如果 n - k + 1 为奇数:s[ 1 : k ]
    2. 如果 n - k + 1 为偶数:s[ 1 : k ]翻转

然后n*n暴力维护答案就好了

代码:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
      
typedef long long LL;
     
typedef unsigned long long ull;
      
const int inf=0x3f3f3f3f;
 
const int N=2e5+100;

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		int n;
		string s;
		cin>>n>>s;
		int ans=1;
		string mmin=s;
		for(int k=1;k<n;k++)
		{
			string temp=s.substr(k);
			string rev=s.substr(0,k);
			if((n-k+1)%2==0)
				reverse(rev.begin(),rev.end());
			temp+=rev;
			if(temp<mmin)
			{
				ans=k+1;
				mmin=temp;
			}
		}
		cout<<mmin<<endl<<ans<<endl;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	return 0;
}
发布了672 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104671183