Two Strings Swaps

Two Strings Swaps CodeForces - 1006D

You are given two strings a and b consisting of lowercase English letters, both of length n. The characters of both strings have indices from 1 to n, inclusive.

You are allowed to do the following changes:

Choose any index i (1≤i≤n) and swap characters ai and bi;
Choose any index i (1≤i≤n) and swap characters ai and an−i+1;
Choose any index i (1≤i≤n) and swap characters bi and bn−i+1.
Note that if n is odd, you are formally allowed to swap a⌈n2⌉ with a⌈n2⌉ (and the same with the string b) but this move is useless. Also you can swap two equal characters but this operation is useless as well.

You have to make these strings equal by applying any number of changes described above, in any order. But it is obvious that it may be impossible to make two strings equal by these swaps.

In one preprocess move you can replace a character in a with another character. In other words, in a single preprocess move you can choose any index i (1≤i≤n), any character c and set ai:=c.

Your task is to find the minimum number of preprocess moves to apply in such a way that after them you can make strings a and b equal by applying some number of changes described in the list above.

Note that the number of changes you make after the preprocess moves does not matter. Also note that you cannot apply preprocess moves to the string b or make any preprocess moves after the first change is made.

Input
The first line of the input contains one integer n (1≤n≤105) — the length of strings a and b.

The second line contains the string a consisting of exactly n lowercase English letters.

The third line contains the string b consisting of exactly n lowercase English letters.

Output
Print a single integer — the minimum number of preprocess moves to apply before changes, so that it is possible to make the string a equal to string b with a sequence of changes from the list above.

Examples
Input
7
abacaba
bacabaa
Output
4
Input
5
zcabd
dbacz
Output
0

题意:
给两个字符串a和b,通过 a[i] 和 b[i] j交换, a[i] 和 a[n - i + 1], b[i] 和 b[n - i + 1] 三种交换使a和b一样,因为一般情况下,仅仅通过这三种变换是不可以让 a 和 b 一样的,所以还有一个预处理,可以把a的某个字符换成任意的字符,问最少要几次这样的预处理后a, b可以通过上面的三种变换使得a 和 b 字符串一样。
题解:
就是要让a[i], a[n - i + 1], b[i], b[n - i + 1] 这四个位置的字符只能有一种或者两种且每种要有两个, 那么就是一个分类讨论了,注意n为奇数的情况,要判断最中间的字符是否一样,不一样也要预处理一次(这都没有写出来,我太菜了qwq)
代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;

char a[100010], b[100010];

int sol(char a, char b, char c, char d){
	int q[50];
	memset(q, 0, sizeof(q));
	q[a - 'a' + 1]++;	//我先用一个数组把四个位置的统计每种字符的个数 
	q[b - 'a' + 1]++;
	q[c - 'a' + 1]++;
	q[d - 'a' + 1]++;
	if(a == b && c == d){	//如果a[i] == a[n - i + 1] 和 b[i] == b[n - i + 1],也就是a字符串两个位置和b的两个位置的字符都一样,就不用预处理 
		return 0;
	}
	else if(a != b && c != d){	//如果a字符串两个位置和b的两个位置的字符都不一样的情况 
		int m = 0, f = 0;	//m计算有多少种字符出现两次,f计算有多少种字符出现了一次 
		for(int i = 1; i <= 27; i++){
			if(q[i] == 2){
				m++;
			}
			else if(q[i] == 1){
				f++;
			}
		}
		if(m == 2) return 0; //如果m == 2就代表有两种字符且每种要有两个,不用预处理 
		else if(f == 4){	//f == 4代表有四个位置上分别有四种不同的字符,要预处理两次,把a的两个位置的字符分别换成和b的两个位置一样 
			return 2;
		}
		else{	//其他情况就是有两种字符,一种了出现3次,一种出现一次,需要预处理一次把出现3次的字符的一个换成另一种字符,预处理一次 
			return 1;
		}
	}
	else if(c == d){	//a的两个位置不同,b的两个位置相同,把a的一个字符换成a的另一个字符,预处理一次 
		return 1;
	}
	else if(a == b){	//b的两个位置不同,a的两个位置相同
		if(a == c || a == d)	//如果b两个字符中有一个和a相同就只用换一次,预处理一次 
			return 1;
		else	//否则要预处理两次 
			return 2;
	}
}

int main(){
	int n;
	while(cin >> n){
		cin >> a >> b;
		int ans = 0;
		for(int i = 0, j = n - 1; i < j; i++, j--){
			ans += sol(a[i], a[j], b[i], b[j]);
		}
		if(n % 2 == 1 && a[n / 2] != b[n / 2]){	//n为奇数的时候要判断最中间的字符是否一样,不一样要预处理一次 
			ans++;
		}
		cout << ans << endl;
	}
}
/*
4
ffff
zfzz
*/

代码也写的好烂, 有时间回来改改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值