zoukankan      html  css  js  c++  java
  • Codeforces 1430E

    Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal


    题意

    给定一个长度为(n)的字符串,每次操作可以交换两个相邻字符,问将原串倒置所需要的最小操作数。


    限制

    (2leq nleq 200000)




    思路

    先将原串(S)倒置存于新字符串(R)内,以下标(i)为循环变量,遍历字符串(R),每次将第(i)个位置的字符从剩余的字符串中移动出来并固定,剩余的字符串称作剩余串

    那么就可以模拟字符移动,每次将字符(R[i])移动到剩余串的第一个位置,表示第(i)个位置的字符完成了移动

    贪心可得,每次从剩余串中将下标最小(R[i])移动到串首,操作次数最少

    那么问题就转化成了记录每个字符剩余串中出现的第一个位置,使用(26)个变量(pos)记录

    先遍历原串(S),将每种字符第一次出现的位置记录在(pos)数组内,(cnt)数组记录每种字符出现的次数

    遍历(R),对于每个字符(t),取出其在剩余串中第一次出现的位置(pos[t])

    由于目的是将其移动到剩余串中的首位置,所以答案增加(pos[t]-1)

    然后将原串中(pos[t])位置的一个字符删除,代表剩余串中删去一个字符

    其后循环(26)个变量,由于删去字符后(pos[t])其后的字符下标全部(-1),故对于每个(pos[i]>pos[t]),需要让(pos[i]-1)

    最后将(cnt[t]-1),如果(cnt[t])非零,则可以直接将指针(pos[t])向右移动寻找下一个字符(t)

    最终复杂度为(O(n imes d),d=26)




    程序

    (405ms/2000ms)

    #include<bits/stdc++.h>
    using namespace std;
    
    string S,R;
    int n,pos[26],cnt[26];
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        
        cin>>n>>S;
        S=" "+S;
        R=S;
        for(int i=1;i<=n;i++)
        {
            int t=S[i]-'a';
            if(pos[t]==0)
                pos[t]=i;
            cnt[t]++;
        }
        
        long long ans=0; //注意答案可能超出int范围
        for(int i=n;i;i--)
        {
            int t=R[i]-'a';
            ans+=pos[t]-1;
            S.erase(pos[t],1); //删去一字符
            cnt[t]--;
            
            for(int j=0;j<26;j++)
                if(pos[j]>pos[t]) //对于每个位置大于pos[t]的
                    pos[j]--;
            
            if(cnt[t]==0)
                pos[t]=0;
            else
            {
                while(S[pos[t]]-'a'!=t) //向右继续查找
                    pos[t]++;
            }
        }
        cout<<ans<<'
    ';
        
        return 0;
    }
    

  • 相关阅读:
    labVIEW学习——属性节点
    MATLAB学习
    WinForm中键盘按键问题
    TextBox的智能感知
    使用脚本操作UpdatePanel中控件的问题
    DBNull.Value,null,String.Empty之间的区别和联系
    Hotmail如何对已经存在的邮件地址进行更改?
    第一个hibernate项目
    html静态实现左边导航右边显示链接页面
    Struts2学习
  • 原文地址:https://www.cnblogs.com/stelayuri/p/13799898.html
Copyright © 2011-2022 走看看