Codeforces Round 966 (Div. 3) C. Numeric String Template

https://codeforces.com/contest/2000/problem/C

题目要求我们判断给定的字符串是否符合一个整数数组所定义的模板。每个字符串都需要满足以下条件才能与模板匹配:

字符串的长度必须与整数数组的长度相同。
整数数组中相同的数字必须对应字符串中相同的字符。例如,如果数组中有两个相同的数字,这两个数字必须在字符串中对应两个相同的字符。
字符串中的相同字符必须对应数组中的相同数字。例如,如果字符串中有两个相同的字符,这两个字符必须在数组中对应两个相同的数字。
输入说明:

第一行包含一个整数 t,表示测试用例的数量。
每个测试用例的第一行包含一个整数 n,表示数组 a 中的元素个数。
第二行包含 n 个整数,表示数组 a 的元素。
第三行包含一个整数 m,表示需要检查的字符串数量。
接下来的 m 行中,每行包含一个字符串 sj,需要检查是否与模板匹配。
输出说明:

对于每个测试用例,输出 m 行。第 i 行输出 "YES" 如果第 i 个字符串与模板匹配,否则输出 "NO"。
示例:

输入:

复制代码
3
5
3 5 2 1 3
2
abfda
afbfa
2
1 2
3
ab
abc
aa
4
5 -3 5 -3
4
aaaa
bcbc
aba
cbcb
输出:

objectivec
复制代码
YES
NO
YES
NO
NO
NO
YES
NO
YES
说明:

第一个测试用例中,"abfda" 符合模板,而 "afbfa" 不符合。
第二个测试用例中,"ab" 和 "aa" 符合模板,而 "abc" 不符合。
第三个测试用例中,"aaaa" 和 "cbcb" 符合模板,而 "bcbc" 和 "aba" 不符合。

我当时想的是用map来存,键是数组的值,值是相同数组的下标,然后我逐步遍历,来判断两个map的值是否相同,但是我过样例的时候发现有点样例不对,我思考了一下,因为map是自动按值的升序来排列的,那我们值相等的情况呢,所以我们需要自定义map排列函数来实现
去网上查了一下

template <typename K, typename V>
vector<pair<K, V>> sortmap(const map<K, V>& m) {
    // 将 map 转换为 vector
    vector<pair<K, V>> sortedVec(m.begin(), m.end());

    // 对 vector 按值排序,如果值相同则按键排序
    sort(sortedVec.begin(), sortedVec.end(), [](const pair<K, V>& a, const pair<K, V>& b) {
        if (a.second == b.second) {
            return a.first < b.first; // 如果值相同,则按键排序
        }
        return a.second < b.second; // 否则按值排序
    });

    return sortedVec;
}

我们最后返回的是vector,排列解决了,那我们的问题就迎刃而解了
 

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<long long,long long> PLL;
typedef unordered_map<int,int> HashII;
typedef unordered_map<char,int> HashCI;
typedef priority_queue<int,vector<int>,greater<int>> heap;
typedef unsigned long long ULL;
typedef unordered_map<string,int> HashSI;
const int INF=0x3f3f3f3f;
const int N=1e5+10;

template <typename K, typename V>
vector<pair<K, V>> sort(map<K, V>& m) {
	vector<pair<K, V>> sortedVec(m.begin(), m.end());
	
	sort(sortedVec.begin(), sortedVec.end(), [](const pair<K, V>& a, const pair<K, V>& b) {
		if (a.second == b.second) {
			return a.first < b.first; 
		}
		return a.second < b.second;    
	});
	
	return sortedVec;
}

void solve() {
	int n;
	cin >> n;
	vector<LL> a(n);
	for (int i = 0; i < n; i++) cin >> a[i];
	int m;
	cin >> m;
	while (m--) {
		string s;
		cin >> s;
		int n1 = s.length();
		
		if (n1 != n) {
			cout << "NO" << "\n";
			continue;
		}
		map<LL, vector<int>> m1;
		map<LL, vector<int>> m2;
		for (int i = 0; i < n; i++) {
			m1[a[i]].push_back(i);
			m2[s[i] - 'a'].push_back(i);
		}
		vector<pair<LL, vector<int>>> a1 = sort(m1);
		vector<pair<LL, vector<int>>> a2 = sort(m2);
		if (a1.size() != a2.size()) {
			cout << "NO" << "\n";
			continue;
		}
		bool st = true;
		for (int i = 0; i < a1.size(); i++) {
			if (a1[i].second != a2[i].second) {
				st = false;
				break;
			}
		}
		if (st) {
			cout << "YES" << "\n";
		} else {
			cout << "NO" << "\n";
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值