“推恩令”——分治法
来源:互联网 发布:微商拍小视频软件 编辑:程序博客网 时间:2024/06/10 12:45
A-01 POJ1854
A palindrome is a string of symbols that is equal to itself when reversed. Given an input string, not necessarily a palindrome, compute the number of swaps necessary to transform the string into a palindrome. By swap we mean reversing the order of two adjacent symbols. For example, the string "mamad" may be transformed into the palindrome "madam" with 3 swaps:swap "ad" to yield "mamda"swap "md" to yield "madma"swap "ma" to yield "madam"
Input
The first line of input gives n, the number of test cases. For each test case, one line of input follows, containing a string of up to 8000 lowercase letters.
Output
Output consists of one line per test case. This line will contain the number of swaps, or “Impossible” if it is not possible to transform the input to a palindrome.
Sample Input
3mamadasflkjaabb
Sample Output
3Impossible2
这道题目的大致意思就是任意给你一个长度不超过8000的小写字符串,可以交换任意两个相邻的(adjacent)字母,要你用最少的交换次数使这个字符串是回文(palindrome)。
这是一道基本的分治题,算法思路就死从两头开始比较,如果两个字母不同,就从除去两头已经符合条件的中间一串字符中寻找能够与两端交换的字母,分别从左右两段开始找,判断两遍那个次数少,然后操作一遍,挨个交换(attention!!!);如果相同就向下扩大左右两段子串范围;
需要注意的是,以上步骤开始之前,可以判断一下是否有多个字母的个数是奇数个,如果有,那么就直接“Impossible”;
下面贴代码:
#include <algorithm>#include <bitset>#include <cassert>#include <climits>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <deque>#include <iomanip>#include <iostream>#include <map>#include <numeric>#include <queue>#include <set>#include <stack>#include <string>#define INF 0x3f3f3f3f#define EPS 1e-6using namespace std;unsigned long len;bool check(int ch[]){ int flag=0; for(int i=0;i<26;i++){ if(ch[i]%2==1)flag++; } if(flag>1)return true; else return false;}int divide(string a,int left,unsigned long right){ int i=left,j=(int)right; int suml=0,sumr=0,sum=0; while(i<j){ int l,r; for(l=i;l<j;l++) if(a[l]==a[j]){suml=l-i;break;} for(r=j;r>i;r--) if(a[r]==a[i]){sumr=j-r;break;} if(l-i<j-r){ sum+=suml; for(int k=l-1;k>=i;k--){ char tmp; tmp=a[k];a[k+1]=a[k];a[k+1]=tmp; } } else { sum+=sumr; for(int k=r+1;k<=j;k++){ char tmp; tmp=a[k];a[k-1]=a[k];a[k-1]=tmp; } } i++;j--; suml=0;sumr=0; } return sum;}int main(){ int n; cin>>n; while(n--){ int ch[26]; memset(ch,0,sizeof(ch)); string a; cin>>a; len=a.size(); for(int i=0;i<a.size();i++){ ch[a[i]-'a']++; } if(check(ch)){cout<<"Impossible"<<endl;continue;} else cout<<divide(a,0,len-1)<<endl; } return 0;}继续刷题!!!
0 0
- “推恩令”——分治法
- 分治法——非等分分治
- 排序——分治法
- 分治法—归并排序
- 算法系列—分治法
- 数据结构—分治法小结
- 算法思想笔记——分治法
- 分治法——二分搜索
- 【算法导论】03——分治法
- 分治法——归并排序
- 算法学习笔记——分治法
- 分治法——循环赛日程安排问题
- 算法之——分治法
- 分治法——最大子数组
- 找中位数问题——分治法
- 求平方根——分治法
- 分治法——算法总结二
- 算法初探——分治法
- [HPU] 机房的位置(三)[二分图最大匹配][匈牙利算法]
- Java程序运行过程
- POJ 2828(线段树点修改 思维)
- Java与js中的多态
- Python:Non-ASCII character
- “推恩令”——分治法
- UnityEditor<三>自定义窗口 案例1
- 无序容器unorder_map使用自定义类型
- 四旋翼之路——前篇
- Android中必须学习的八大开源项目
- MFC_快速使用01
- iOS XCode的weak 引用细节
- myeclipse cannot be resolved to a type
- 生成简单验证码的JSP页面