【2017.10.24考试 T1 】Frank原创。
题目描述
当你终于打通 Codevs 钻石天梯, 成为一名 Master 后。在 11 月 11 日这一天,
响应万能的评测机的召唤, 加入了恢弘的魔术师战争中。
但评测机却在大战开幕前被污染了//被卡了,意外导致你手背上的令咒排列顺
序被随机打乱, 令咒表现为一长度确定的字符串 B。 而身为古老魔术家族的传
人, 你发现家族世代相传的文献记载了令咒原有的模样为字符串 A, 你考虑对
比两个令咒, 将你手背上的令咒修改为原有的模样, 修改规则如下:
1. 每次可以交换 B 令咒中相邻两个字符的位置。
2. 根据等价交换的准则,修改令咒会消耗魔力, 你想要使 A, B 相同,并希望
交换次数最少。
3. 若无法将 B 修改为 A,输出“-1” 。
输入格式
输入文件 order.in。
第一行一个整数 n,表示字符串的长度
接下来两行,每行一个字符串 A, B。
输出格式
输出文件 order.out。
一个整数为最小交换次数(若不能交换则输出“-1”)
样例输入
5
AB?@C
A?CB@
样例输出
3
数据范围及提示
数据保证不存在重复字符
对于 20%的数据: 1<=n<=20
对于 100%的数据: 1<=n<=100
20%貌似是BFS
正解是类似于冒泡排序的做法?
不管不管暴力模拟。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=500+5;
int n,tot,sum;
char a[maxn],b[maxn];
bool u[maxn];
bool p;
map<char,int>m1;
map<char,int>m2;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) cin>>a[i],m1[a[i]]=i;//每个字符的位置
for(int i=1;i<=n;i++) cin>>b[i],m2[b[i]]=i;//对b进行操作
for(int i=1;i<=n;i++)
{
if(a[i]==b[i]) continue;
else if(a[i]!=b[i])//找到不一样的字符
{
tot=m2[a[i]];//从a中第i个字符在b中出现的位置开始往前交换
for(int j=tot;j>=i;j--)
{
if(j==i&&b[i]==a[i])//换到相同为止
break;
else
{
m2[b[j-1]]++;//被交换的整体后移
swap(b[j],b[j-1]);//注意更新顺序
sum++;//交换次数
}
if(j==i&&a[i]!=b[j])
p=1;//找不到
}
}
}
if(p==1) puts("-1\n");
else printf("%d",sum);
return 0;
}