Codeforces 1384C. String Transformation 1(模拟)

Note that the only difference between String Transformation 1 and String Transformation 2 is in the move Koa does. In this version the letter 𝑦 Koa selects must be strictly greater alphabetically than 𝑥 (read statement for better understanding). You can make hacks in these problems independently.

Koa the Koala has two strings 𝐴 and 𝐵 of the same length 𝑛 (|𝐴|=|𝐵|=𝑛) consisting of the first 20 lowercase English alphabet letters (ie. from a to t).

In one move Koa:

selects some subset of positions 𝑝1,𝑝2,…,𝑝𝑘 (𝑘≥1;1≤𝑝𝑖≤𝑛;𝑝𝑖≠𝑝𝑗 if 𝑖≠𝑗) of 𝐴 such that 𝐴𝑝1=𝐴𝑝2=…=𝐴𝑝𝑘=𝑥 (ie. all letters on this positions are equal to some letter 𝑥).
selects a letter 𝑦 (from the first 20 lowercase letters in English alphabet) such that 𝑦>𝑥 (ie. letter 𝑦 is strictly greater alphabetically than 𝑥).
sets each letter in positions 𝑝1,𝑝2,…,𝑝𝑘 to letter 𝑦. More formally: for each 𝑖 (1≤𝑖≤𝑘) Koa sets 𝐴𝑝𝑖=𝑦.
Note that you can only modify letters in string 𝐴.

Koa wants to know the smallest number of moves she has to do to make strings equal to each other (𝐴=𝐵) or to determine that there is no way to make them equal. Help her!

Input
Each test contains multiple test cases. The first line contains 𝑡 (1≤𝑡≤10) — the number of test cases. Description of the test cases follows.

The first line of each test case contains one integer 𝑛 (1≤𝑛≤105) — the length of strings 𝐴 and 𝐵.

The second line of each test case contains string 𝐴 (|𝐴|=𝑛).

The third line of each test case contains string 𝐵 (|𝐵|=𝑛).

Both strings consists of the first 20 lowercase English alphabet letters (ie. from a to t).

It is guaranteed that the sum of 𝑛 over all test cases does not exceed 105.

Output
For each test case:

Print on a single line the smallest number of moves she has to do to make strings equal to each other (𝐴=𝐵) or −1 if there is no way to make them equal.

Example
inputCopy
5
3
aab
bcc
4
cabc
abcb
3
abc
tsr
4
aabd
cccd
5
abcbd
bcdda
outputCopy
2
-1
3
2
-1
Note
In the 1-st test case Koa:
selects positions 1 and 2 and sets 𝐴1=𝐴2= b (𝑎𝑎𝑏→𝑏𝑏𝑏).
selects positions 2 and 3 and sets 𝐴2=𝐴3= c (𝑏𝑏𝑏→𝑏𝑐𝑐).
In the 2-nd test case Koa has no way to make string 𝐴 equal 𝐵.
In the 3-rd test case Koa:
selects position 1 and sets 𝐴1= t (𝑎𝑏𝑐→𝑡𝑏𝑐).
selects position 2 and sets 𝐴2= s (𝑡𝑏𝑐→𝑡𝑠𝑐).
selects position 3 and sets 𝐴3= r (𝑡𝑠𝑐→𝑡𝑠𝑟).

题意:
你可以选择一些相同字母,同时变成更大的字母(前20个小写字母)。
求将A变成B的最小次数

思路:
写了个贪心,假了。

其实只要考虑字母即可,也就20*20。
然后直接模拟,先枚举最小字母,将其变成相邻最近的字母。
用map模拟这个过程就OK了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<unordered_map>
#include<map>

using namespace std;
typedef long long ll;

int f[26][26];
char s1[100005],s2[100005];
map<pair<int,int>,int>mp;

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        int n;scanf("%d",&n);
        scanf("%s%s",s1 + 1,s2 + 1);
        mp.clear();
        int flag = 0;
        for(int i = 1;i <= n;i++) {
            if(s1[i] > s2[i]) flag = 1;
            if(s1[i] != s2[i] && s2[i] > 't') {
                flag = 1;
            }
            if(s1[i] != s2[i]) mp[{s1[i] - 'a',s2[i] - s1[i]}] = 1;
        }
        if(flag) {
            printf("-1\n");
            continue;
        }
        int ans = 0;
        for(auto it = mp.begin();it != mp.end();it++) {
       
        for(int i = 0;i < 20;i++) { //首字符
            int pos = 100;
            for(int j = 1;j < 20;j++) { //距离
                if(mp[{i,j}]) {
                    ans++;
                    pos = j;
                    mp[{i,j}] = 0;
                    break;
                }
            }
            for(int j = pos + 1;j < 20;j++) {
                if(mp[{i,j}]) {
                    mp[{i,j}] = 0;
                    mp[{i + pos,j - pos}] = 1;
                }
            }
        }
        
        printf("%d\n",ans);
    }
    return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值