码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces#297 B Pasha and Strini

时间:2015-03-28 14:29:53      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:dp   algorithm   codeforces   

题意:给一个字符串,交换m次,每次交换a[i]~n-a[i]+1的字符(例如a[i]=2,n-5,则s[2]和s[4]换)。

思路:暴力时间复杂度是10^5*10^5,pass。在交换中,我们可以先把多余的交换去掉。每个字符交换次数若为偶数,一定不变。为奇数,再交换一次即可。

f[i]表示[i,n-i-1]段交换次数,n/2之后全部等价成1~n/2的。dp[i]表示每个字符交换的次数。注意字符串长度是奇数还是偶数,需分开讨论!

本题关键是找到每段字符串交换次数与每个字符交换次数的递推关系式:dp[i]=dp[i-1]+f[i]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
#define ll __int64
#define INF 0x3fffffff
#define N 2*100005
using namespace std;

char s[N];
int m;
int a[N];
int f[N];//[i,n-i-1]段交换次数
int dp[N];//每位需交换次数

int main()
{
    //freopen("d:\\Test.txt","r",stdin);
    cin>>s;
    cin>>m;
    memset(f,0,sizeof(f));
    memset(dp,0,sizeof(dp));
    int n=strlen(s);
    for(int i=0;i<m;i++){
        cin>>a[i];
    }
    if(n%2==0){
        for(int i=0;i<m;i++){
            if(a[i]<=n/2){
                f[a[i]]++;
            }else{
                f[n-a[i]+1]++;
            }
        }
        dp[1]=f[1];
        for(int i=2;i<=n/2;i++){
            dp[i]=dp[i-1]+f[i];
        }
    }
    else{
        for(int i=0;i<m;i++){
            if(a[i]<n/2){
                f[a[i]]++;
            }else{
                f[n-a[i]+1]++;
            }
        }
        dp[1]=f[1];
        for(int i=2;i<=n/2;i++){
            dp[i]=dp[i-1]+f[i];
        }
    }
    for(int i=0;i<=n/2;i++){
        if(dp[i+1]&1) swap(s[i],s[n-i-1]);
    }
    cout<<s<<endl;
    return 0;
}



Codeforces#297 B Pasha and Strini

标签:dp   algorithm   codeforces   

原文地址:http://blog.csdn.net/u012198382/article/details/44699603

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!