51nod 1335 子序列翻转

来源:互联网 发布:apache subversion 编辑:程序博客网 时间:2024/06/15 22:39
初始有一个字符串s,串的长度L不超过2500。你可以对串中一个子串进行一次翻转,确切的说,你可以选择一对整数
{ x,y } 其中0<=x<=y<L,然后翻转字符串中索引在x到y区间上的子串,将该串从s[x]s[x+1]...s[y]变为s[y]...s[x+1]s[x]。例如, s = "abcdefg",{ x,y } 取 { 2,5 } 那么翻转后是 "abfedcg",如果取 { 0,1 } 结果是 "bacdefg",如果取 { 3,3 } 那结果是 "abcdefg"(即没变)。你的目的是翻转一次后,使字符串的字典序尽可能的小,那么问最优的 { x,y } 是多少?如果存在多组解能使s变化后字典序最小,那么输出其中x最小的那组解,如果还有多组解,那么输出y最小的解。


Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5之后有T组结构相同的数据:每组包含一行一个字符串s,其中s的长度L满足1<=L<=2500且s只包含小写字母'a'~'z'
Output
一组数据输出一行两个整数,即最优的翻转子序列的区间索引x,y
Input示例
2abdcaabbcc
Output示例
2 3

0 0

出发点就固定的,就是第一个不在自己应该在的地方的那个数。如何找这个位置,就是排序一下对比着找即可。

之后从当前出发点开始往后找,如果第i个小于出发点,交换,比较一下总串大小,如果小于之间出现过的最小值,更新y。

之后i继续往后找。最后输出y即可

#include <bits/stdc++.h>using namespace std;string str1,str2;string jiaohuan(string s,int x,int y){    for(int i=x;i<=(x+y)/2;i++)    {        swap(s[i],s[y-i+x]);    }    return s;}int main(){    int t,x,y;    cin>>t;    while(t--)    {        x=0;        y=0;        cin>>str1;        str2=str1;        int len=str2.size();        sort(&str2[0],&str2[0]+len);        for(int i=0;i<len;i++)        {            if(str1[i]>str2[i])            {                x=i;                y=i;                break;            }        }        string str3=str1,str4;        for(int i=x+1;i<len;i++)        {            if(str1[i]<=str1[x])            {                str4=jiaohuan(str1,x,i);                if(str4<str3)                {                    str3=str4;                    y=i;                }            }        }        cout<<x<<" "<<y<<endl;    }}

原创粉丝点击