Codeforces 思维训练(四)

D. Sakurako's Hobby

题目链接:Problem - 2008D - Codeforces

求每个点可以到达多少个点,即求的是每个点和多少个点之间是联通的,用并查集即可完成。

// Problem: D. Sakurako's Hobby
// Contest: Codeforces - Codeforces Round 970 (Div. 3)
// URL: https://codeforces.com/problemset/problem/2008/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 
const int N = 2e5 + 10;
int n;
int f[N];
int find(int x)
{
	if(x == f[x]) return x;
	return f[x] = find(f[x]);
}
void init()
{
	for(int i=1;i<=n;i++) f[i] = i;
}
bool is(int x,int y)
{
	x = find(x);
	y = find(y);
	if(x == y) return true;
	return false;
}
void join(int x,int y)
{
	x = find(x);
	y = find(y);
	if(x == y) return ;
	f[x] = y;
}
void solve()
{
	cin>>n;vector<int> a(n+1);init();
	for(int i=1;i<=n;i++) cin>>a[i];
	string s;cin>>s;s = "*" + s;
	vector<int> ans(n+1);
	for(int i=1;i<=n;i++)
	{
		if(s[i] == '0') ans[i] = 1;
	}
	for(int i=1;i<=n;i++)
	{
		if(!is(a[i],i))
		{
			join(a[i],i);
			ans[find(i)] += ans[a[i]];
		}
	}
	for(int i=1;i<=n;i++) cout<<ans[find(i)]<<' ';cout<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B1. The Strict Teacher (Easy Version)

题目链接:Problem - 2005B1 - Codeforces

因为只有两个老师,所以学生采取最佳策略就是:

  • 如果学生在两个老师的左边 那么他可以跑到最左边
  • 如果学生在两个老师的右边 那么他可以跑到最右边
  • 如果学生在两个老师的中间 那么他采取最优策略也只是在两个老师中间 

代码如下:

// Problem: B1. The Strict Teacher (Easy Version)
// Contest: Codeforces - Codeforces Round 972 (Div. 2)
// URL: https://codeforces.com/problemset/problem/2005/B1
// Memory Limit: 256 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n,m,k;cin>>n>>m>>k;
	int a,b,idx;
	cin>>a>>b;cin>>idx;
	int x = min(a,b);int y = max(a,b);
	if(x == idx || y == idx) 
	{
		cout<<0<<endl;
		return ;
	}
	if(x > idx) cout<<x - 1LL<<endl;
	else if(y < idx) cout<<n - y<<endl;
	else cout<<((y - x) >> 1LL)<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Game with Doors

题目链接:Problem - 2004B - Codeforces

因为他俩不会在同一个房间中,所以如果他们的区间有交集的话,交集内的所有房间都要上锁,因为你也不知道他们具体在哪里,然后就是考虑边界情况了:没有交集就是1,只需要关闭连个集合之间的任意一个门就行了,有交集就关闭包含的边界即可。

// Problem: B. Game with Doors
// Contest: Codeforces - Educational Codeforces Round 169 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/2004/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 
#define ok return ;
void solve()
{
	int a,b,c,d;cin>>a>>b>>c>>d;
	int ans = min(b,d) - max(a,c);//两集合是否有交集 ∩
	if(ans < 0) ans = 1;//没有交集 ∩
	else//有交集的话就最少要把交集内的门都关上
	{
		ans += (a != c);//加上边界的门
		ans += (b != d);
	}
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

C. Numeric String Template

题目链接:Problem - 2000C - Codeforces

只需要在遍历的时候将所对应的两个映射存起来并判断一不一样就行了,注意判断键是否存在不要用判断值是否为0,而是要用mp.count(键名) 。

// Problem: C. Numeric String Template
// Contest: Codeforces - Codeforces Round 966 (Div. 3)
// URL: https://codeforces.com/problemset/problem/2000/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 
//map判断键是否存在的时候 需要用到mp.count(键名) 防止本来就是初始值
void solve()
{
	int n;cin>>n;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	int q;cin>>q;
	while(q--)
	{
		bool f = 1;
		string s;cin>>s;
		map<char,int> mp;map<int,char> pm;
		s = "*" + s;
		if(s.size() != n + 1)
		{
			NO;
			continue ;
		}
		for(int i=1;i<=n;i++)
		{
			char ch = s[i];
			if(mp.count(ch) == 0)
			{
				if(pm.count(a[i]) && ch != pm[a[i]])
				{
					f = 0;
					break;
				}
				mp[ch] = a[i];
				pm[a[i]] = ch;
			}
			else
			{
				if(a[i] == mp[ch]) continue;
				f = 0;
				break;
			}
		}
		if(f)
		YES
		else NO
	}
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Removals Game

题目链接:Problem - 2002B - Codeforces

我们只需要判断a和b一样不一样或者a和b反过来一样不一样就行了,因为每次都是从头或尾取,如果当前头尾元素都不一样了,那么你取走一个之后,我就会选择在之后的取数中保留你刚刚取走的那个,最终我就会赢。

// Problem: B. Removals Game
// Contest: Codeforces - EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)
// URL: https://codeforces.com/problemset/problem/2002/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define x "Alice"
#define y "Bob"
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+1),b(n+1);
	for(int i=1;i<=n;i++) cin >> a[i];
	for(int i=1;i<=n;i++) cin >> b[i];
	if(a == b)
	{
		cout<<y<<endl;
		return ;
	}
	reverse(a.begin()+1,a.end());
	if(a == b)
	{
		cout<<y<<endl;
		return ;
	}
	cout<<x<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

C. Splitting Items

题目链接:Problem - 2004C - Codeforces

要想使得最后的代价最小,我们可以每次选取较大的,所以首先对数组排序,都是采取最佳策略,那么我们就尽量把使用的k次操作添加使得数组中的较大元素相等,这样就能保证差值最小。

// Problem: C. Splitting Items
// Contest: Codeforces - Educational Codeforces Round 169 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/2004/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n,k;cin>>n>>k;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a.begin()+1,a.end(),greater<int>());
	int ans = 0;bool f = 1;
	for(int i=1;i<=n;i++)
	{
		if(f) ans += a[i];
		else
		{
			 ans -= a[i];
			 int cha = a[i-1] - a[i];
			 if(k >= cha)
			 {
			 	ans -= cha;
				 k -= cha;
			 }
			 else
			 {
			 	ans -= k;
			 	k -= k;
			 }
		}
		f = !f;
	}
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Minimize Equal Sum Subarrays

题目链接:Problem - 1998B - Codeforces

要想使得最终的相同元素最少,而且全都是排列,也就是说每个元素会且仅会出现一次,那么我们就只需要将元素组进行错位即可。

// Problem: B. Minimize Equal Sum Subarrays
// Contest: Codeforces - Codeforces Round 965 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1998/B
// Memory Limit: 256 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	cout<<a[n]<<' ';
	for(int i=1;i<n;i++) cout<<a[i]<<' ';
	cout<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B1. Bouquet (Easy Version)

题目链接:Problem - 1995B1 - Codeforces

滑动窗口滑一遍即可。

// Problem: B1. Bouquet (Easy Version)
// Contest: Codeforces - Codeforces Round 961 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1995/B1
// Memory Limit: 512 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n,k;cin>>n>>k;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a.begin() + 1,a.end());
	int l = 1,r = 0,ans = 0,sum = 0;
	while(r < n)
	{
		r++;
		sum += a[r];
		while(l <= r && (sum > k || a[r] - a[l] > 1)) sum -= a[l],l++;
		ans = max(ans,sum);
	}
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Fun Game

题目链接:Problem - 1994B - Codeforces

对于字符串s来说,当前位置为1,要想变为0,需要的是1,如果当前位置是0,要想变为1,还是需要1,所以我们可以发现,如果这个位置的两个元素不相同了,那么我们是需要在前面有1的。

因为可以使用无数次,而异或又有可逆性,所以我们只需要判断前面有没有1就行了,受到档期操作异或影响的元素可以再异或回去。

// Problem: B. Fun Game
// Contest: Codeforces - Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2)
// URL: https://codeforces.com/problemset/problem/1994/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define endkl endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;string s,t;cin>>n>>s>>t;
	if(s == t)
	{
		YES
		return ;
	}
	int x = s.find("1");
	int y = t.find("1");
	if(x == -1 && y != x)
	{
		NO
		return ;
	}
	for(int i=0;i<n;i++)
	{
		if(s[i] != t[i])
		{
			if(x > i)
			{
				NO
				return ;
			}
		}
	}
	YES
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

C. Even Positions

题目链接:Problem - 1997C - Codeforces

尽量填右括号即可,思路为:如果当前位置是左括号,那么要在后面添加右括号,所以ans ++,但是如果当前元素是右括号的话,我们就需要用之前的最后一个右括号的位置的后一个(初始为0)填的左括号来和当前右括号进行匹配。

// Problem: C. Even Positions
// Contest: Codeforces - Educational Codeforces Round 168 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/1997/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;
	string s;cin>>s;
	int cnt = 0,f = 0;
	for(int i=1;i<s.size();i+=2)
	{
		if(s[i] == '(') cnt ++;
		if(s[i] == ')')
		{
			cnt += i - f;
			f = i + 1LL;
		}
	}
	cout<<cnt<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Parity and Sum

题目链接:Problem - 1993B - Codeforces

因为每次选择的两个数的奇偶性不同,所以在操作之后就需要将所有的元素都变为奇数才行,所以如果全为奇或全为偶就输出0,否则就需要全部变成奇,这时候我们可以用最大的奇数和偶数进行操作,如果当前的偶数小于最大奇数的话,就ans++,直接让这两个数相加,使得这个偶数变为了一个新的最大奇数,然后以此类推,所以一般情况答案就是偶数的个数,但是有特殊情况:一旦出现有偶数大于这个最大奇数了,那么我们就需要让最大的奇数和最大的偶数相加,使得这个最大的奇数变为最大的!这也就需要额外多操作一次即可。

// Problem: B. Parity and Sum
// Contest: Codeforces - Codeforces Round 963 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1993/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n);
	for(int i=0;i<n;i++) cin>>a[i];
	vector<int> ji,ou;
	for(auto &i : a)
	{
		if(i & 1) ji.push_back(i);
		else ou.push_back(i);
	}
	if(ji.size() == 0 || ou.size() == 0)
	{
		cout<<0<<endl;
		return ;
	}
	sort(ji.begin(),ji.end());
	sort(ou.begin(),ou.end());
	int mx = ji[ji.size() - 1];
	bool f = 0;
	for(auto &i : ou)
	{
		if(i < mx) mx += i;//不断地用最大的奇数来操作
		else f = 1;//与最大的偶数进行操作 变为最大的奇数
	}
	cout<<(f ? ou.size() + 1LL : ou.size())<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. AND Reconstruction

题目链接:Problem - 1991B - Codeforces

因为b[i]是受到a[i]和a[i+1]影响的,所以a[i]和a[i+1]需要对b[i]进行或操作,然后再遍历一遍看是否合法即可。

// Problem: CF1991B AND Reconstruction
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1991B
// Memory Limit: 250 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 
const int N = 1e5 + 10;
vector<int> a(N),b(N);
void init()
{
	fill(a.begin(),a.end(),0LL);
}
void solve()
{
	init();
	int n;cin>>n;
	for(int i=1;i<n;i++) cin>>b[i];
	for(int i=1;i<n;i++)
	{
		for(int j=0;j<=30;j++)
		if(b[i] >> j & 1) a[i] |= 1LL << j,a[i+1] |= 1LL << j;
	}
	bool f = 1;
	for(int i=1;i<n;i++)
	if((a[i] & a[i+1]) != b[i])
	{
		f = 0;
		break;
	}
	if(f == 0) cout<<"-1";
	else
	for(int i=1;i<=n;i++) cout<<a[i]<<' ';
	cout<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

当然也可以将按位或操作改为:

a[i] |= b[i];
a[i+1] |= b[i];

B. K-Sort

题目链接:Problem - 1987B - Codeforces

首先肯定是要统计每一个位置都差了多少,然后要加上有多少组操作就行了。

  • 每一个位置差多少可以用一个数组来存放这个位置之前的最大值然后减去当前这个位置就是需要多少
  • 有多少组操作就是将差的数量存入一个map中,然后统计map中最大的键即可(千万不是map的大小!!!)
// Problem: B. K-Sort
// Contest: Codeforces - EPIC Institute of Technology Round Summer 2024 (Div. 1 + Div. 2)
// URL: https://codeforces.com/problemset/problem/1987/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+2);
	for(int i=1;i<=n;i++) cin>>a[i];
	vector<int> l(n+1,0),r(n+1,0);
	for(int i=1;i<=n;i++) l[i] = max(l[i-1],a[i]);
	// for(int i=n;i>=1;i--) r[i] = max(r[i+1],a[i]);
	int ans = 0;
	map<int,int> mp;
	// for(int i=2;i<=n;i++)
	// {
		// if(a[i] < a[i-1])
		// {
			// mp[l[i] - a[i]] ++;
		// }
	// }
	// for(auto &i : mp)
	// {
		// ans += (1LL + i.fi * i.se);
	// }
	vector<int> cha;
	for(int i=1;i<=n;i++)
	{
		if(l[i] - a[i] > 0) 
		{
			// cha.push_back(l[i] - a[i]);
			ans += l[i] - a[i];
			mp[l[i] - a[i]] ++;
		}
	}
	int mx = 0,sum = mp.size(),f = 0;
	for(auto &i : mp) mx = max(mx,i.fi);
	// ans += mp.size();
	ans += mx;
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

C. Update Queries

题目链接:用贪心的思想去想,要想使得字典序最小,那么我们是不是就可以将可替换的最小的字符尽量往前来。

// Problem: C. Update Queries
// Contest: Codeforces - Codeforces Round 954 (Div. 3)
// URL: https://codeforces.com/problemset/problem/1986/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n,m;cin>>n>>m;vector<int> index(m+1);
	map<int,char> mp;
	string s;cin>>s;s = " " + s;
	for(int i=1;i<=m;i++)
	{
		cin>>index[i];
	}
	string t;cin>>t;sort(t.begin(),t.end());t = " " + t;
	sort(index.begin() + 1,index.end());
	int l = 1;
	for(int i=1;i<=m;i++)
	{
		if(index[i] == index[i-1]) continue;
		s[index[i]] = t[l++];
	}
	string ans = s.substr(1,s.size() - 1);
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Matrix Stabilization

题目链接:Problem - 1986B - Codeforces

模拟题,我们只需要判断每个点周围的最大值,即这个点最少能减少到多少即可。

// Problem: B. Matrix Stabilization
// Contest: Codeforces - Codeforces Round 954 (Div. 3)
// URL: https://codeforces.com/problemset/problem/1986/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n,m;cin>>n>>m;
	vector<vector<int>> e(n+2,vector<int> (m+2,-inf));
	vector<vector<int>> mx(n+2,vector<int> (m+2,-inf));
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++) cin>>e[i][j];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int u = e[i][j-1];
			int d = e[i][j+1];
			int l = e[i-1][j];
			int r = e[i+1][j];
			mx[i][j] = max({u,d,l,r});
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cout<<min(e[i][j],mx[i][j])<<' ';
		}
		cout<<endl;
	}
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

C. Good Prefixes

题目链接:Problem - 1985C - Codeforces

首先需要弄清楚的一点就是既然这个元素是其他元素的和,那么这个元素就一定是当前所有元素中的最大值,所以我们只需要用一个数记录当前的和和当前的最大值然后进行比较即可。

// Problem: C. Good Prefixes
// Contest: Codeforces - Codeforces Round 952 (Div. 4)
// URL: https://codeforces.com/problemset/problem/1985/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	vector<int> sum(n+1,0);
	for(int i=1;i<=n;i++) sum[i] = sum[i-1] + a[i];
	// vector<bool> v()
	// map<int,bool> mp;
	int mx = 0;
	int ans = 0;
	for(int i=1;i<=n;i++)
	{
		mx = max(mx,a[i]);
		if(mx == sum[i] - mx) ans ++;
		
	}
	cout<<ans<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Large Addition

题目链接:Problem - 1984B - Codeforces

因为必须是大整数之间的和,所以一定会进位,而通过5,6,7,8,9为个位的元素亮亮相加之后能够得到以1,2,3,4,5,6,7,8结尾的数,所以判断结尾是不是9就行,其次,因为会有进位的情况所以开头一定是1,所以也可以通过这个条件来判断,同时:又因为会进位,所以中间的每一位都不能出现数字0,只要满足以上三种情况,就是符合条件的了,反之则不是。

// Problem: B. Large Addition
// Contest: Codeforces - Codeforces Global Round 26
// URL: https://codeforces.com/problemset/problem/1984/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int x;cin>>x;
	string s = to_string(x);
	// string s;cin>>s;
	if(s[0] != '1' || s[s.size() - 1] == '9')
	{
		NO
		return ;
	}
	int index = 0;
	for(auto &i : s)
	{
		index ++;
		if(index == s.size()) break;
		if(i == '0')
		{
			NO
			return ;
		}
	}
	YES
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Increase/Decrease/Copy

题目链接:Problem - 1976B - Codeforces

可以增加1,也可以减少1,那么首先就需要计算每个位置的元素都相差多少,然后就是考虑复制最后一个元素的贪心最优策略了:

  • 很明显,如果在增加或减少的过程中出现了这个数,那么直接复制一遍即可,代价为1,而如果没有出现,我们就只需要每次都判断一下如果是当前元素复制的话需要花费多少代价,最后遍历结束后取最小值即可。
// Problem: B. Increase/Decrease/Copy
// Contest: Codeforces - Educational Codeforces Round 166 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/1976/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define endkl endl;
inline int lowbit(int x)
{
	return x & (-x);
} 
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	int mx_a = a[1];int mi_a = a[1];
	// for(int i=1;i<=n;i++) mx_a = max(mx_a,a[i]),mi_a = min(mi_a,a[i]);
	vector<int> b(n+2);int ans = 0;
	for(int i=1;i<=n+1;i++) cin>>b[i];
	for(int i=1;i<=n;i++) ans += abs(a[i] - b[i]);
	int index = b[n+1];// map<int,int> mp;
	int k = inf;
	for(int i=1;i<=n;i++)
	{
		if(index >= min(a[i],b[i]) && index <= max(a[i],b[i])) k = 0;
		else if(index < min(a[i],b[i])) k = min(k,min(a[i],b[i]) - index);
		else if(index > max(a[i],b[i])) k = min(k,index - max(a[i],b[i]));
	}
	cout<<ans + k + 1<<endkl
	// int index = b[n+1];int mx_b = b[1],mi_b = b[1];
	// for(int i=1;i<=n;i++) mx_b = max(mx_b,b[i]),mi_b = min(mi_b,b[i]);
	// int mi = min(mi_a,mi_b);int mx = max(mx_a,mx_b);
	// if(index <= mx && index >= mi) cout<<ans+1<<endl;
	// else if(index > mx) cout<<ans + 1 + abs(index - mx)<<endl;
	// else cout<<ans + 1 + abs(index - mi)<<endl;
	// sort(b.begin() + 1,b.end());
	
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. Binary Colouring

题目链接:Problem - 1977B - Codeforces

首先肯定是要转化为二进制,然后又因为:

  • 因为 2 ^ i + 2 ^ i+1 == 2 ^ i+2 - 2 ^ i

  • 所以 0 1 1  -> 1 0 -1

只需要对不合条件的连续的两个1变为1和0即可,只需要对进位的情况进行判断即可。

// Problem: B. Binary Colouring
// Contest: Codeforces - Codeforces Round 948 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1977/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define endkl endl;
inline int lowbit(int x)
{
	return x & (-x);
} 
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	//因为2 ^ i + 2 ^ i+1 == 2 ^ i+2 - 2 ^ i
	//所以0 1 1  -> 1 0 -1
	int x;cin>>x;vector<int> er(50,0);int cnt = 0;
	while(x)
	{
		er[++cnt] = (x&1LL);
		x >>= 1LL;
	}
	for(int i=1;i<40;i++)
	{
		if(er[i] == 2)
		{
			er[i] = 0;
			er[i+1] ++;
		}
		if(er[i] == 1 && er[i+1] == 1)
		{
			er[i] = -1;
			er[i+1] = 0;
			er[i+2] ++;
		}
	}
	for(int i=1;i<50;i++)
	{
		if(er[i]) cnt = max(cnt,i);
	}
	cout<<cnt<<endl;
	for(int i=1;i<=cnt;i++) cout<<er[i]<<' ';
	cout<<endl;
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

B. 378QAQ and Mocha's Array

题目链接:Problem - 1975B - Codeforces

模拟即可,看是否会超出两个答案。

// Problem: B. 378QAQ and Mocha's Array
// Contest: Codeforces - Codeforces Round 947 (Div. 1 + Div. 2)
// URL: https://codeforces.com/problemset/problem/1975/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define pii pair<int,int>
#define fi first
#define se second
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define endkl endl;
inline int lowbit(int x)
{
	return x & (-x);
} 
const int INF = 0x3f3f3f3f;
const int inf = 1e18; 

void solve()
{
	int n;cin>>n;vector<int> a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a.begin() + 1,a.end());
	int index1 = a[1],index2 = -1;
	for(int i=2;i<=n;i++) 
	{
		if(a[i] % index1)
		{
			index2 = a[i];
			break;
		}
	}
	if(index2 == -1)
	{
		YES
		return ;
	}
	for(int i=2;i<=n;i++)
	{
		if(a[i] % index1)
		{
			if(a[i] % index2)
			{
				NO
				return ;
			}
		}
	}
	YES
//	cout<<fixed<<setprecision(x)<< ; 
}

signed main()// Don't forget pre_handle!
{
	IOS
	int T=1;
	cin>>T;
	while(T--) solve(); 
	return 0;
} 

### Codeforces 编程练习题 Codeforces 是一个广受欢迎的在线编程竞赛平台,提供了大量不同难度级别的题目供用户练习。对于希望提升算法能力的学习者来说,该平台是一个非常有价值的资源。 #### 数学类题目 一些数学类型的题目可以帮助提高逻辑思维能力和解决问题的能力。例如,在CSDN博客上有一篇关于Codeforces简单数学题的文章进行了详细的总结[^1]。这些题目通常涉及数论、组合数学和其他基础数学概念的应用。 #### 字符串变换问题 另一个有趣的类别是字符串处理题目。比如在Educational Codeforces Round 39 中有一个名为 "String Transformation" 的挑战[C. String Transformation][^2]。这类题目往往考察选手对字符操作的理解以及如何高效地转换给定条件下的字符串序列。 #### 提升技巧的方法 为了更好地利用Codeforces来增强解题技能并达到更高的评级水平,可以从以下几个方面入手: - **克服弱点**:通过分析个人比赛表现找出薄弱环节(如动态规划、图论等问题),针对性加强训练。 - **构建工具库**:创建常用数据结构和算法模板(像区间最值查询(RMQ),树状数组(BIT), 线段树等),这有助于加快编码速度减少错误率[^3]。 ```cpp // 这里给出一段简单的RMQ实现作为例子 #include <vector> using namespace std; class RMQ { vector<int> rmq; public: void build(const vector<int>& nums){ int n = nums.size(); rmq.resize(n * 4); construct(nums, 0, n - 1, 1); } private: void construct(const vector<int>& nums,int l ,int r ,int node){ if(l == r){ rmq[node]=nums[l]; return ; } int mid=(l+r)/2; construct(nums,l,mid,node*2); construct(nums,mid+1,r,node*2+1); rmq[node]=min(rmq[node*2],rmq[node*2+1]); } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值