【队内胡策】令咒

12 篇文章 0 订阅
9 篇文章 0 订阅

【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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值