Codeforces Round 855 (Div 3)(A - F)

Codeforces Round 855 (Div. 3)(A - F)

Codeforces Round 855 (Div. 3)

A. Is It a Cat?(思维)

思路:先把所有字母变成小写方便判断 , 然后把每一部分取一个字母出来 , 判断和‘meow’是否相同即可。

复杂度 O ( n ) 复杂度O(n) 复杂度O(n)

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , t;

string s;

bool judge(string s){
	string now;
	for(int i = 0 ; i < n ; i ++) if(i == 0 || s[i] != s[i - 1]) now += s[i];
	return now == "meow";
}

signed main(){

	IOS
	cin >> t;
	
	while(t --) {
		cin >> n >> s;
		for(int i = 0 ; i < n ; i ++) s[i] = tolower(s[i]);
		if(judge(s)) {
			cout << "YES\n";
		} else {
			cout << "NO\n";
		}
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

B. Count the Number of Pairs(模拟 + 贪心)

思路:先贪心的把能合并的合并掉 , 然后对于不能合并的进行操作即可。

复杂度 O ( n ) 复杂度O(n) 复杂度O(n)

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int cnt1[30] , cnt2[30];
int t , n , k;
string s;
signed main(){

	IOS
	cin >> t;
	
	while(t --){
		cin >> n >> k;
		cin >> s;
		for(int i = 0 ; i < n ; i ++){
			if(s[i] >= 'a' && s[i] <= 'z') cnt1[s[i] - 'a' + 1] += 1;
			else cnt2[s[i] - 'A' + 1] += 1;
		}
		int res = 0;
		for(int i = 1 ; i <= 26 ; i ++){
			int now = min(cnt1[i] , cnt2[i]);
			res += now;
			cnt1[i] -= now;
			cnt2[i] -= now;
		}
		for(int i = 1 ; i <= 26 ; i ++){
			int now = cnt1[i] / 2;
			if(now <= k){
				k -= now;
				res += now;
			} else {
				res += k;
				k = 0;
				break;
			}
		}
		for(int i = 1 ; i <= 26 ; i ++){
			int now = cnt2[i] / 2;
			if(now <= k){
				k -= now;
				res += now;
			} else {
				res += k;
				k = 0;
				break;
			}
		} 
		for(int i = 1 ; i <= 26 ; i ++) cnt1[i] = cnt2[i] = 0;
		cout << res << "\n";
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

C. Powering the Hero(优先队列)

思路:模拟一下不难发现 , 每次取走英雄牌的时候要在前面没使用的附加牌中选择一张力量值最大的 , 用优先队列维护即可。

复杂度 O ( n l o g n ) 复杂度O(nlogn) 复杂度O(nlogn)

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int t , n , now;

signed main(){

	IOS
	cin >> t;
	
	while(t --){
		cin >> n;
		priority_queue<int , vector<int> , less<int>> q;
		int res = 0;
		for(int i = 1 ; i <= n ; i ++){
			cin >> now;
			if(now) {
				q.push(now);
			} else {
				if(q.size()){
					res += q.top();
					q.pop();
				}
			}
		}
		cout << res << "\n";
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

D. Remove Two Letters(思维)

思路:删除两个连续字符 ,对于任意三个字符来说 , 删除 1 , 2 位置的剩余 3 号位置 ,删除 2 , 3 号位置剩余 1 号位置 , 如果 1 3 号位置相同 , 则剩余字符串必定相同 。 即 i 号字符如果和 (i + 2) 号字符相同 , 那么就会产生一个重复答案 , 考虑最多有 n - 1 个答案 , 从中减去重复答案即可。

复杂度 O ( n ) 复杂度O(n) 复杂度O(n)

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int t , n;
string s;

signed main(){

	IOS
	cin >> t;
	
	while(t --){
		cin >> n >> s;
		int res = n - 1;
		for(int i = 0 ; i < n - 2 ; i ++){
			if(s[i] == s[i + 2]) res -= 1;
		}
		cout << res << "\n";
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

E. Unforgivable Curse(并查集维护集合 , 思维)

思路:考虑 位置 x 可以与 y 进行交换 , 位置 y 可以与 位置 z 进行交换 , 操作三次就相当于在 y 不动的情况下交换了 x , z , 这样在同一个集合中任意两个元素都可以在不影响其余位置的情况下互相交换 ,那么显然一个集合中的字符可以表示任意种类和数目相同的字符串。比较所有集合字符的种类和数量是否相同即可 , 用并查集 和 multiset 维护集合 , 比较即可。

复杂度 O ( n l o g n ) 复杂度O(nlogn) 复杂度O(nlogn)

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

/*
并查集
*/

int t , n , k ;
string st , ed;
int fa[N];

int find(int x){
	if(x == fa[x]) return x;
	else return fa[x] = find(fa[x]);
}

void unionn(int x , int y){
	int xx = find(x);
	int yy = find(y);
	fa[xx] = yy;
}

signed main(){

	IOS
	cin >> t;
	
	while(t --){
		cin >> n >> k;
		cin >> st >> ed;
		st = '#' + st;
		ed = '#' + ed;
		for(int i = 1 ; i <= n ; i ++) fa[i] = i;
		for(int i = 1 ; i <= n ; i ++){
			int x = i + k;
			int y = i + k + 1;
			if(x <= n) unionn(i , x);
			if(y <= n) unionn(i , y);
		}
		multiset<char>st1[n + 10] , st2[n + 10];
		set<int>all;
		for(int i = 1 ; i <= n ; i ++) {
			int now = find(i);
			all.insert(now);
			st1[now].insert(st[i]);
			st2[now].insert(ed[i]);
		}
		bool tag = 0;
		for(auto x : all){
			if(st1[x] != st2[x]) tag = 1;
		}
		if(!tag) cout << "YES\n";
		else cout << "NO\n";
	}

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

F. Dasha and Nightmares(状态哈希)

思路:对于三个条件 , 满足了后两个条件第一个条件自然就满足了 , 所以思考如何处理后两个条件。即:

  • 恰好出现 25 个字母
  • 每个字母出现次数为奇数

我们不妨再次弱化条件 , 思考只有条件三如何去做 。

如果暴力的去做 , 复杂度是O(n ^ 2 * 26) , 显然不能接受 ,对于奇偶性 , 考虑哈希压缩状态 , 把每一个串压缩成一个 26 位的二进制串 , 0 代表当前位是偶数 , 1 代表当前位是奇数 , 那么前面满足条件的状态就是当前二进制状态按位取反后的状态 ,这样就能就做到了O(n)。

考虑加上第二个约束 , 恰好出现了 25 个字母 ,如果我们还是按照前面那样寻找显然是不行的 , 因为二进制位 0 既可以代表 0 次也能代表偶数次 , 考虑维护 26 个哈希表 , 代表第 i 个字母没出现的状态集合 , 遍计数边维护即可。

复杂度 O ( 26 ∗ n ∗ l o g n ) 复杂度O(26*n*logn) 复杂度O(26nlogn)

由于带log复杂度比较极限 , 需要实现的精细一点 ,用 unordered_map 且每次访问之前判断是否有值 , 避免多次访问空值。

#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n , m;
unordered_map<int , int>mp[30];
int cnt[N][30] , pre[N] , nex[N];
string s;
int res;

signed main(){

	IOS
	cin >> n;
	for(int i = 1 ; i <= n ; i ++) {
		cin >> s;
		m = s.size();
		for(int j = 0 ; j < m ; j ++) cnt[i][s[j] - 'a' + 1] += 1;
		for(int j = 0 ;  j < 26 ; j ++) {
			pre[i] += (cnt[i][j + 1] % 2) * (1 << j);
			nex[i] += (1 - cnt[i][j + 1] % 2) * (1 << j);
		}
	}
	
	// a - z
	
	for(int i = 1 ; i <= n ; i ++){
		for(int j = 0 ; j < 26 ; j ++){
			if(cnt[i][j + 1]) continue;
			int k = nex[i] - (1 << j);
			if(mp[j + 1].find(k) != mp[j + 1].end()) res += mp[j + 1][k];
			mp[j + 1][pre[i]] += 1;
		}
		
	}
	
	cout << res << "\n";

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

你可能感兴趣的:(cocoa,macos,objective-c)