Codeforces Round 888 (Div. 3)(A~F) ---Day11

1851A - Escalator Conversations 

        题意:给定n个人的高度h和你自己的高度H,给定一个数m和数字k,求你和某个人的高度差为k的倍数且0 < 高度差/k < m 的个数。

        思路:直接模拟即可。

        

void solve() 
{
	int n , m , k , H;
	cin>>n>>m>>k>>H;
	int h[n];
	for(int i = 0; i < n ; i ++)
		cin>>h[i];
	int ans = 0;
	for(int i =0 ; i < n ; i ++){
		int s = abs(h[i] - H);
		if(s!= 0 && s % k == 0){
			if(s / k < m)
				ans++;
		}
	}
	cout<<ans<<endl;
}    

1851B - Parity Sort          

        题意:给定一个数组n,你可以交换奇偶性相同的两个数,求整个数组能否变为非递减序列。

        思路:首先记录原始数组的奇偶性,然后将奇数、偶数分为不同两组进行排序,然后再根据原数组的奇偶性按顺序填入奇数偶数,最后判断整个数组是否非递减。

void solve() 
{
	int n;
	cin>>n;
	vector<int> odd,even;
	int a[n];
	for(int i = 0; i < n ; i ++){
		cin>>a[i];
		if(a[i]%2 == 1){
			odd.pb(a[i]);
		}
		else{
			even.pb(a[i]);
		}
	}
	sort(odd.begin() , odd.end() , cmp);
	sort(even.begin() , even.end() ,cmp);
	int ans[n],cnt1 = 0 , cnt0 = 0;
	for(int i = 0; i < n ; i ++){
		if(a[i] % 2 == 0){
			ans[i] = even[cnt0++];
		}
		else
			ans[i] = odd[cnt1++];
	}
	int f = 1;
	for(int i = 1 ; i < n ; i ++){
		if(ans[i] < ans[i - 1]){
			cout<<"NO\n";	
			return;	
		}
	}
	cout<<"YES\n";
}   

1851C - Tiles Comeback 

        题意:给定一个整数k和长度为n的格子,每个格子有一个数字。你需要从a_{1}跳跃到a_{k}。规定你可以向右跳跃任意数量,你的路径为每次所在格子的数。路径从前往后可以分为若干个长度为k的块,且每个块之内的数相同。

        思路:已知开始所在a_{1},最后所在a_{n}。根据贪心思想,若a_{1} \neq a_{n}时,只需要满足路径当中前k个数为a_{1},后k个数为a_{n}即可。若a_{1} = a_{n}时,只需要满足共有k个数为a_{1}即可。

void solve() 
{
	int n , k;
	cin>>n>>k;
	int c[n + 5];
	for(int i = 1; i <= n ; i ++){
		cin>>c[i];
	}
	int end = n;
	int cnt = 0;
	if(c[1] == c[n]){
		for(int i = 1 ; i<= n ; i++){
			if(c[i] == c[1])
				cnt++;
		}
	}
	else{
		for( ; end>0;end--){
		if(c[end] == c[n])
			cnt++;
		if(cnt == k)
			break;
		}
		cnt = 0;
		for(int i = 1 ; i< end ; i++){
			if(c[i] == c[1])
				cnt++;
		}
	}
	if(cnt >= k)
		cout<<"YES";
	else
		cout<<"NO";
	cout<<endl;
}     

1851D - Prefix Permutation Sums 

        题意:有一个长度为n的数组,给定了其前缀和数组,其中前缀和数组中缺失了一个。求补全前缀和数组后能否使得原数组为一个排列(排列的定义为1~n所有的数有且仅有1个)。

        思路:通过前缀和数组我们可以得到n - 1 个数字。此时分两种情况来讨论:1、前缀和数组的尾缺失了。2、前缀和数组缺失了其余位置数。情况1:尾部缺失,如果得到的n-1个数字可以与排列中的不同数字一一对应,那么加上尾部后能够组成序列。情况2:中间缺失的话,这n - 1个数当中有一个数代表了原数组中的a_{i} + a_{i + 1}。若n - 2个数能与原序列当中不同数字一一对应,且剩下的两个没有对应数字相加为余下的那一个数,则能够组成序列。综上,只需要记录一下有多少个数字能与序列匹配然后再判断即可。

void solve() 
{
	int n;
	cin>>n;
	LL sum[n + 5];
	sum[0] = 0;
	int isv[n + 5];
	memset(isv , 0 , sizeof isv);
	for(int i = 1; i < n ;i ++){
		cin>>sum[i];
	}
	queue<LL>idx;
	for(int i = 1 ; i < n ; i ++){
		idx.push(sum[i] - sum[i - 1]);
	}
	LL res = 0;
	for(int i = 1 ; i < n ; i ++){
		LL id = idx.front();
		idx.pop();
		if(id > n){
			res = id;
		}
		else if(isv[id] == 1){
			res = id;
		}
		else{
			isv[id] = 1;
		}
	}
	LL k = 0;
	int cnt = 0;
	for(int i = 1 ; i <= n ; i++){
		if(isv[i] == 0){
			cnt++;
			k +=i;
		}
	}
	if(cnt == 1){
		cout<<"YES\n";
	}
	else if(k != res || cnt > 2){
		cout<<"NO\n";
	}
	else{
		cout<<"YES\n";
	}
//	cout<<res<<endl;
}     

1851E - Nastya and Potions 

        题意:有n种药剂,其中你有p种药剂是免费的,其中一种药剂可以通过其他的药剂混合而成或者通过购买花费金币获得。给定每个药剂的配方,若无配方则只能通过购买获得。求获得每个药剂的最小金币数。

        思路:典型的记忆化搜索题目,dp(i)表示求第i种药剂所花费的最小金币数,cost[i]表示第i种药剂所花费的最小金币数,isv[i]表示是否已经算出了cost[i],用容器e[i]表示合成第i种药剂所需要的药剂。若cost[i]已经求出来了,则标记一下,下次直接返回cost[i]即可。cost[i] = min(cost[i] , \sum_{j = 0}^{e[i].size() - 1} (cost[e[i][j]]))

LL cost[N];
int isv[N];
vector<LL>e[N];
LL dp(int n){
	if(isv[n] == 1)
		return cost[n];
	LL co = 0;
	for(int i = 0 ; i < e[n].size() ; i++){
		co += dp(e[n][i]);
	}
	cost[n] = min(cost[n] , co);
	isv[n] = 1;
	return cost[n];
}
void solve() 
{
	int n , p;
	cin>>n>>p;
	for(int i = 1 ; i <= n ; i++){
		cin>>cost[i];
		isv[i] = 0;
		e[i].clear();
	}
	for(int i = 0 ; i < p ; i++){
		int num;
		cin>>num;
		cost[num] = 0;
	}
	for(int i = 1 ; i <= n ; i++){
		int op;
		cin>>op;
		if(op == 0){
			isv[i] = 1;
		}
		else{
			for(int j = 0 ; j < op ; j ++){
				int num;
				cin>>num;
				e[i].pb(num);
			}
		}
	}
	for(int i = 1;  i <= n ; i++){
		cout<<dp(i)<<" ";
	}
	cout<<endl;
}       

1851F - Lisa and the Martians 

        题意:给定一个整数k,给定n个整数,其中每个数 < 2^k。从中选取两个数和一个任意数x。求小于2*k的(a_{i} \oplus x)\&(a_j \oplus x)的最大值。

         思路:假设(a_{i} \oplus x)\&(a_j \oplus x) = y 。对于每一位来说,若a_{im} =a_{jm},则y_{m} = 1(m为二进制所在位数)。则y = ((1 << k) - 1) \oplus (a_{i} \oplus a_{j})。因此(a_{i} \oplus a_{j})越小越好。求异或最小值用trie树解决(没写出来)。求两数异或值最小,还可以通过排序后求相邻数对异或的最小值。

PII a[N];
int cmp(PII a, PII b){
	return a.first < b.first;
}
void solve ()
{
	int n, k;
	cin >> n >> k;
 
	for (int i = 1; i <= n; i++) {
		cin >> a[i].first;
		a[i].second = i;
	}
	sort (a+1, a + n+1 , cmp);
	int idx,minx=2e9;
	for (int i = 2; i <= n; i++) {
		if (minx > (a[i].first ^ a[i - 1].first)) {
			minx = a[i].first ^ a[i - 1].first;
			idx = i;
		}
	}
	int m = ((1 << k) - 1) ^ a[idx].first;
	cout << a[idx].second << " " << a[idx-1].second << " " << m << endl;
}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值