#150. 魔法书密码

it2022-05-05  190

#150. 魔法书密码

统计 描述 提交 自定义测试 【题目描述】: 哪里有压迫,哪里就有反抗。

moreD的宠物在法庭的帮助下终于反抗了。作为一只聪明的宠物,他打算把魔法师moreD的魔法书盗去,夺取moreD的魔法能力。但moreD怎么会让自己的魔法书轻易地被盗取?moreD在魔法书上设置了一个密码锁,密码锁上有一个问题。

施以《斯卧铺》魔法吧,你有M次机会,如此将得完美密码。

然后是一串小写字母串。

moreD的宠物《斯卧铺》魔法就是施法时的字符串其中相邻两位交换。

而moreD对于完美密码的定义自然是最小字典序了。

请帮助moreD的宠物,想出密码吧。

【输入描述】: 第一行一个整数M,表示操作次数。

第二行一串小写字母组成的字符串S,如题目所示。

【输出描述】: 输出完美密码。

【样例输入】: 3 dcba 【样例输出】: adcb 【样例说明】: 先对第3,4两位施法,字符串变成dcab,然后对第2,3两位施法,字符串变成dacb,最后对第1,2两位施法,字符串变成adcb。

【时间限制、数据范围及描述】: 时间:1s 空间:256M

对于30%的数据|S|<=10

对于60%的数据|S|<=3,000

对于100%的数据8<=|S|<=100,000 M<=(|S|-8)^2+2

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <string> #include <cstring> #include <cmath> using namespace std; typedef long long ll; ll M; int len; int C[100005],next[100005],head[26]; char S[100005]; inline void add(int x,int pos) { next[pos]=head[x]; head[x]=pos; } inline void update(int x,int v) { for(int i=x; i<=len; i+=i&-i) C[i]+=v; } inline int query(int x) { if(x==0) return 0; int res=0; for(int i=x; i>0; i-=i&-i) res+=C[i]; return res; } int main() { scanf("%lld",&M); scanf("%s",&S); len=strlen(S); for(int i=len-1; i>=0; i--) add(S[i]-'a',i+1); for(int i=1; i<=len; i++) update(i,1); for(int i=0; i<len; i++) { int j; for(j=0; j<26; j++) { int tmp; if(head[j]!=0&& (tmp=query(head[j]-1))<=M) { M-=tmp; update(head[j],-1); head[j]=next[head[j]]; break; } } printf("%c",j+'a'); } return 0; }

最新回复(0)