1. 程式人生 > >uva 10716 Evil Straw Warts Live(貪心回文串)

uva 10716 Evil Straw Warts Live(貪心回文串)

人的 family 移動 set 每次 ans tchar 代碼 namespace

這道題目我用了一上午才做出來,還是看的別人的思路,盡管沒有看代碼做的有點慢。代碼能力還是得加強啊。思維

得縝密。不能想當然,要有根據,寫上的代碼要有精確度。省的以後還得慢慢調試

思路:貪心。每次都查看兩端位置上的字母是否相等。若不相等就在裏面查找能使他們相等且所需移動位置最少的那

個。然後交換。記錄交換的距離,貪心的離最後一個由近及遠找與第一個位置相等的。同理貪心從第一個位置找和最

後一個位置相等且離第一個位置近期的。

。感覺這樣的方法確實能夠,可是並不會證明這樣的策略的正確性。。

代碼:

#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(貪心回文串)