contest: Codeforces Round #297 (Div. 二), problem: (B) Pasha and String
Pasha got a very beautiful string s for his birthday, the string consists of lowercase Latin letters. The letters in the string are numbered from 1 to |s| from left to right, where |s| is the length of the given string.
Pasha didn't like his present very much so he decided to change it. After his birthday Pasha spent m days performing the following transformations on his string — each day he chose integer ai and reversed a piece of string (a segment) from position ai to position|s| - ai + 1. It is guaranteed that 2·ai ≤ |s|.
You face the following task: determine what Pasha's string will look like after m days.
The first line of the input contains Pasha's string s of length from 2 to 2·105 characters, consisting of lowercase Latin letters.
The second line contains a single integer m (1 ≤ m ≤ 105) — the number of days when Pasha changed his string.
The third line contains m space-separated elements ai (1 ≤ ai; 2·ai ≤ |s|) — the position from which Pasha started transforming the string on the i-th day.
In the first line of the output print what Pasha's string s will look like after m days.
abcdef 1 2
aedcbf
vwxyz 2 2 2
vwxyz
abcdef 3 1 2 3
fbdcea
转置与顺序无关,比如 1 2 3 4 5 和 5 4 3 2 1的转置顺序结果是一样的,所以先进行排序,删除成对的且相同的,同一部分转置两次相当于没转;
其实还可以简化,刚开始嫌麻烦就这样交了..于是超时了..刚好卡在最后一组数据上..
于是要进一步优化,例如一个长度为10的串,输入 5 4 3 2 2 1 先排序,删掉两个2,剩下 1 3 4 5
即 1-10,3-8,4-7,5-6 先看前两个 3-8转了两次 所以只需要转置 1,2,与9,10即可 同理 只要交换4与7即可
这样不仅运行次数减少了一半以上,而且每次执行的任务也大大减少了,于是只花了31ms
code = =
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn1=200000+100,maxn2=100000+100; char str[maxn1]; ///全局变量!! int a[maxn2]; ///char s[6]; void reve(int p,int q) ///第一步优化,不用把数组作为参数加进来了 { for(int i=p;i<=(p+q)/2;i++) { char c=str[i]; str[i]=str[p+q-i]; str[p+q-i]=c; } } void change(int a,int b,int c,int d) ///第二步优化 { for(int i=a;i<=b;i++) { char c=str[i]; str[i]=str[a+d-i]; str[a+d-i]=c; } } int main() { /// s[0]='h';s[1]='e';s[2]='l';s[3]='l';s[4]='o',s[5]='\0'; /// reve(0,4); /// printf("%s\n",s); while(~scanf("%s",str)) { int len=strlen(str); /// printf("%s\n",str); int m; scanf("%d",&m); ///刚开始又忘了输入m了 = = 真心无奈... for(int i=0;i<m;i++) scanf("%d",a+i); sort(a,a+m); /// for(int i=0;i<m;i++) /// printf("%d\n",a[i]); for(int i=0;i<m-1;i++) ///i<m-1 if(a[i]==a[i+1]&&a[i]!=0) a[i]=0,a[i+1]=0; ///a[i]!=0 int flag=2; int k,t; for(int i=0;i<m;i++) { if(a[i]) { if(flag==2) flag--,k=a[i]-1; ///选出第一个没被删的数 else if(flag==1) flag--,t=a[i]-1; ///第二个没被删的数,这两个数一定不相等 } if(!flag) change(k,t-1,len-t,len-k-1),flag=2; ///优化2 } if(flag==1) reve(k,len-1-k); /// 是否存在落单的数 /// for(int i=0;i<m;i++) /// if(a[i]) reve(a[i]-1,len-a[i]); printf("%s\n",str); } return 0; }