标签:
这道题目我用了一上午才做出来,还是看的别人的思路,虽然没有看代码做的有点慢,代码能力还是得加强啊,思维
得缜密,不能想当然,要有依据,写上的代码要有准确度,省的以后还得慢慢调试
思路:贪心,每次都查看两端位置上的字母是否相等,若不相等就在里面查找能使他们相等且所需移动位置最少的那
个,然后交换,记录交换的距离,贪心的离最后一个由近及远找与第一个位置相等的,同理贪心从第一个位置找和最
后一个位置相等且离第一个位置最近的。。。感觉这种方法确实可以,但是并不会证明这种策略的正确性。。。
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set> #include<string> #include<algorithm> using namespace std; int a[30]; string s; void swap1(int x,int y) { char ch = s[x]; for(int i=x; i<y; i++) { s[i] = s[i+1]; } s[y] = ch; return ; } void swap2(int x,int y) { char ch = s[y]; for(int i=y; i>x; i--) { s[i] = s[i-1]; } s[x] = ch; return ; } int cost; void solve() { int i,j; for(i=0; i<(s.size()/2); i++) { //cout << "i = "<<i << endl; if(s[i]!=s[s.size()-1-i]) { for(j=1; j<=s.size()-1-1-i-i; j++) { if(s[j+i]== s[s.size()-1-i])//判断是否和最后一个相等,若相等就放到对称位置 { swap2(i,i+j);//准确写出移动函数 //cout << s << endl; cost += j;//移动距离 break; } else if(s[s.size()-1-i-j] == s[i])//判断是否和第一个相等,若相等就和最后一个互换,即它的最后一个位置(这里所说第一个位置是当前判断的位置不是全部序列的第一个) { swap1(s.size()-1-i-j,s.size()-1-i);//注意调用的移动函数是否可行 //cout << s << endl; cost+= j; break; } } } } return ; } int main() { int T,i; int ans; cin >> T; getchar(); while(T--) { ans = 0; memset(a,0,sizeof(a)); s.clear(); cin >> s; getchar(); for(i=0; i<s.size(); i++) { a[s[i]-'a']++; } int flag = 0; for(i=0; i<26; i++)//预处理是否可以构成回文数 { if(a[i]%2!=0) { ans++; } } cost = 0; if(ans > 1) cout << "Impossible" << endl; else { solve(); cout << cost << endl; } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
uva 10716 Evil Straw Warts Live(贪心回文串)
标签:
原文地址:http://blog.csdn.net/sinat_22659021/article/details/47336711