Super-palindrome(思维题)

问题 A: Super-palindrome

时间限制: 1 Sec  内存限制: 128 MB
提交: 560  解决: 210
[提交] [状态] [命题人:admin]

题目描述

You are given a string that is consisted of lowercase English alphabet. You are supposed to change it into a super-palindrome string in minimum steps. You can change one character in string to another letter per step.
A string is called a super-palindrome string if all its substrings with an odd length are palindrome strings. That is, for a string s, if its substring si...j satisfies j - i + 1 is odd then si+k = sj-k for k = 0,1,...,j-i+1.

输入

The fi rst line contains an integer T (1≤T≤100) representing the number of test cases.
For each test case, the only line contains a string, which consists of only lowercase letters. It is guaranteed that the length of string satisfies 1≤|s|≤100.

输出

For each test case, print one line with an integer refers to the minimum steps to take.

样例输入

复制样例数据

3
ncncn
aaaaba
aaaabb
样例输出
0
1
2
提示
For second test case aaaaba, just change letter b to a in one step.

题意:

给你一串小写字母组成的字符串。你需要用最少的步骤把这个字符串变成超级回文串。每个步骤你都可以把字符串里的一个字符变成其它字符。

超级回文串 :一个字符串它的所有长度为奇数的子串都是回文串

思路:

就是要让奇数位上的都是同一个元素,偶数位上的都是同一元素,所以就可以,分别记录奇数位,和偶数位上出现的字母,分别找出奇数位出现最多的字母的数量max1,和偶数位出现最多的字母的数量max2,len-max1-max2就是要变换的字母的数量

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int vis1[30],vis2[30];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int max1=-1,max2=-1;
		memset(vis1,0,sizeof(vis1));
		memset(vis2,0,sizeof(vis2));
		string s;
		cin>>s;
		int len=s.length() ;
		for(int i=0;i<len;i++){
			if(i%2==0)
			    vis2[s[i]-'a']++;
			else
			    vis1[s[i]-'a']++;
		}
		for(int i=0;i<30;i++){
			if(max1<vis1[i])
			    max1=vis1[i];
			if(max2<vis2[i])
			    max2=vis2[i];
		}
		printf("%d\n",len-max1-max2);
	}
	return 0;
} 

 还可以动态的查找,需要变动的最小次数,每到一个字母,都要看在奇数(偶数)项里边,全部字母都变成这一种所需要的个数,每次都取最小,偶数最小count1,奇数最小count2,所求的=count1+count2

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		string s;
		cin>>s;
		int len=s.length() ;
		int count1=99999;
		int count2=99999;
		int count;
		for(int i=0;i<len;i++){
			count=0;
			if(i%2==0){
				for(int j=0;j<len;j+=2){
					if(s[j]!=s[i])
					    count++;
				}
				count1=min(count1,count);
			}
			else{
				for(int j=1;j<len;j+=2){
					if(s[j]!=s[i])
					    count++;
				}
				count2=min(count2,count);
			}
		}
		printf("%d\n",count1+count2);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/red_red_red/article/details/89065130