完美的代价 - 双向搜索
题目地址:http://www.51cpc.com/web/problem.php?id=1178
Summarize:
1. 两个指针分别从起始与末尾向中间扫描,直到相遇;
2. 判断无解情况:①数组长度为偶数且所有字母均为偶数个;
②奇数次字母不只一个;
3. 若数组长度为奇数,则可能奇数次的字母只需加上到中点的步数,无需移动,
若移动该字母可能使得答案偏多,可看做将该字母最后一个移动;
abb abbcc bbccaxx
4. 不要漏了首指针与尾指针本来相等的情况;
附代码:
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 #define LL long long 6 int n; 7 string a; 8 9 int main() 10 { 11 while(cin>>n) 12 { 13 cin>>a; 14 15 LL ans=0; 16 int e=n-1, odd=0, can=1; 17 for(int i=0; i<e; i++) { 18 int j=e; 19 while(a[j]!=a[i] && j>i) j--; 20 21 if(e == j) { 22 e--; 23 continue; 24 } 25 26 if(i == j) { //single one 27 odd++; 28 if(!(n%2) || odd>1) { 29 can=0; 30 cout<<"Impossible"<<endl; 31 break; 32 } 33 ans += n/2-i; //not need to move 34 continue; 35 } 36 37 ans += e-j; 38 char p = a[i]; 39 for(int k=j; k<e; k++) 40 a[k] = a[k+1]; 41 a[e] = p; 42 // cout<<i<<' '<<e<<' '<<a<<' '<<ans<<endl; 43 e--; 44 } 45 46 if(can) cout<<ans<<endl; 47 } 48 49 return 0; 50 }