51Nod 1335 思维

该博客详细解析了51Nod的1335题,讨论如何通过排序和字符交换来达到字符串最小字典序的要求。博主提出先将字符串排序,然后找到第一个不同字符的位置作为交换起点,并枚举交换终点,通过模拟翻转过程寻找最优解。算法复杂度为O(Tn^2)。
摘要由CSDN通过智能技术生成

题目链接


思路:
根据题意,要求最终字符串的字典序最小,则要求原字符串的小字符尽量换到前面,大的字符换到后面。

考虑将字符串从小到大排序,则与原字符一一比较后的第一个不同的字符一定是交换的起点,假设其在原串的位置为 p o s pos pos

然后考虑枚举交换的终点,因为原字符串的终点字符一定是排序后新串的第 p o s pos pos个位置的字符。

若存在多个,则模拟翻转,与答案比较并更新。

总复杂度: O ( T n 2 ) O(Tn^2) O(Tn2)

代码:

#include<cmath>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
string s,ne,ans,tem;
int main(){
    ios::sync_with_stdio(false);
    int T;cin >> T;
    while(T--){
        cin >> s;ne = s;
        sort(ne.begin(),ne.end());
        int len = s.length();

        int pos = len;
        for(int i=0 ;i<len ;i++){
            if(s[i] > ne[i]){
                pos = i;
                break;
            }
        }
        if(pos == len) cout << 0 << " " << 0 << endl;
        else{
            ans = s;
            int st = pos,ed = st;
            for(int i=pos+1 ;i<len ;i++){
                if(s[i] != ne[pos]) continue;
                tem = s;
                reverse(tem.begin()+pos,tem.begin()+i+1);
                if(tem < ans){ans = tem;ed = i;}
            }
            cout << st << " " << ed << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值