[codeforces 1316B] String Modification 力挽狂澜

CodeCraft-20 (Div. 2)   比赛人数7369

[codeforces 1316B] String Modification   力挽狂澜

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.ml/contest/1316/problem/B

ProblemLangVerdictTimeMemory
B - String Modification GNU C++11Accepted218 ms24600 KB

题目清晰流畅,没有任何问题。问题出现在解题过程。

1≤t≤5000,1≤n≤5000,在想算法的时间复杂度是O(t*n),或者O(t*nlogn)。

同时,又进行着数据的手工模拟,模拟过程中,不断的跳出O(t*nlogn)这样的时间复杂度怎么可能实现。

手工模拟进行得也很不顺利。B题陌生度大,心想,今天交代在这。

切换到C题,感觉也不顺,因为能放在C题,肯定不是菜题,在状态混乱时,能做出的也只有菜题。

重新切换回B题,做了个决定,全力攻克B题,这场比赛能AC,题A题B即可,再不济,只AC,题A,也行,这个任务目前已经完成。

后果,会排名的大幅下降,这个不要紧,就像做生意有赔有赚是一样的.排名于我,只是个数字,能力与我,才是相伴一生的实力.

再次读题,发现It is guaranteed that the sum of n over all test cases does not exceed 5000这句,也就是算法的时间复杂度

达到5000*5000是可以的,也即O(n^2),时间复杂度宽松了,那就全力研究该题算法。

手工模拟了样例的第一条数据,感觉象冒泡排序。

因字母模拟,眼花缭乱,故接下来的模拟针对数字,数字代表字母在字符串中的位置

算法:字串切成2段,后段前移,顺序不变;前段后移,注意后移的这部分顺序会变

接下来,每个长度为n的字串衍生出n个字串(k=1,k=2,...,k=n对应的字串),按字典序,找出最小的字串。

模拟过程如下

123456

k=1结果123456,模拟过程如下
123456    数据顺序不变

k=2结果234561,模拟过程如下
123456
213456
231456
234156
234516
234561    1跑到最后,顺序不变的23456跑到前头

k=3结果345612,模拟过程如下
123456
321456
341256
345216
345612    12跑到最后,顺序不变的3456跑到前头.12前头有3456共4个数字,每移过1个数字,12顺序要变换1次

k=4结果456321,模拟过程如下
123456
432156
451236
456321    123跑到最后,顺序不变的456跑到前头,123前头有456共3个数字,每移过1个数字,123顺序要变换1次

k=5结果561234,模拟过程如下
123456
543216
561234    1234跑到最后,顺序不变的56跑到前头,1234前头有56共2个数字,每移过1个数字,1234顺序要变换1次

k=6结果654321,模拟过程如下
123456
654321    逆序

算法明白后,该题怎么遍,就看读者,自个的做法了,以下是比赛时AC代码。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 5010
using namespace std;
struct node{
	int k;
	char s[maxn];
}q[maxn];
int cmp(node a,node b){
	return strcmp(a.s+1,b.s+1)==0?a.k<b.k:strcmp(a.s+1,b.s+1)<0;
}
int main(){
	int t,n,i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		scanf("%s",q[0].s+1);
		for(i=1;i<=n;i++){
			q[i].k=i;
			for(j=1;j<=n-i+1;j++)q[i].s[j]=q[0].s[i+j-1];
			if((n-(i-1))%2==0){//顺序
				for(;j<=n;j++)q[i].s[j]=q[0].s[j-(n-i+1)];
			}else{
				for(;j<=n;j++)q[i].s[j]=q[0].s[i-(j-(n-i+1))];
			}//逆序
			q[i].s[n+1]='\0';
		}
		sort(q+1,q+1+n,cmp);
		printf("%s\n",q[1].s+1);
		printf("%d\n",q[1].k);
	}
	return 0;
}

比赛任务,艰难完成。力挽狂澜,一看,还有时间,继续下一题。不管C题成功与否,比赛中制定的任务圆满完成。

上一场的比赛也不简单。最近codeforces有些难。

吐槽,比赛中,不少是团队作战,一个做出,团队也就做出了。单兵作战好,还是团队作战好?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值