CodeCraft-20 (Div. 2) 比赛人数7369
[codeforces 1316B] String Modification 力挽狂澜
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.ml/contest/1316/problem/B
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
B - String Modification | GNU C++11 | Accepted | 218 ms | 24600 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有些难。
吐槽,比赛中,不少是团队作战,一个做出,团队也就做出了。单兵作战好,还是团队作战好?