完美的代价 - 双向搜索

题目地址: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 }

 

posted @ 2018-07-27 17:14  liubilan  阅读(137)  评论(0编辑  收藏  举报