当前位置:   article > 正文

Codeforces Round #700 (Div. 2)_e. continuous city codeforces round #700 (div. 2)

e. continuous city codeforces round #700 (div. 2)

A:Yet Another String Game

  题目大意是Alice和Bob轮流对一个字符串进行操作,每轮他俩都必须选择一个字符并对其作出修改。Alice的目标是让这个字符串的字典序尽可能小,Bob的目标是让这个字符串的字典序尽可能大,问双方操作后的新字符串是什么。
  按顺序模拟,注意考虑字符本身是’a’和’z’的情况即可。

#include<bits/stdc++.h>
#define close ios::sync_with_stdio(false)
using namespace std;
int main()
{
	close;int T;cin>>T;
	while(T--)
	{
		string s;cin>>s;
		for(int i=0;i<s.length();++i)
		{
			if(i&1){if(s[i]=='z') s[i]='y';else s[i]='z';}
			else{if(s[i]=='a') s[i]='b';else s[i]='a';}
		}
		cout<<s<<endl;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

B:The Great Hero

  题目大意是英雄和一群怪兽都有一个初始的攻击值和生命值,可以对同一个怪兽发动多次攻击,如果所有的怪兽死亡(哪怕英雄也在最后一轮战斗中死去)就输出“YES”,否则输出“NO”。
  延续了B题不坑你几发罚时就誓不为人的风格 。首先要对怪兽按照攻击值从小到大排序,因为可能有 b [ i ] % A ! = 0 b[i]\%A!=0 b[i]%A!=0,英雄就需要多打一次,也就给自身多造成了 a [ i ] a[i] a[i]点的伤害。先处理小的目的是为了实现英雄血量不够的情况下还能发动最后一次攻击然后和最后一只怪兽一起死亡的现象
在这里插入图片描述

#include<bits/stdc++.h>
#define close ios::sync_with_stdio(false)
using namespace std;
const int maxn=1e5+100;
typedef long long ll;
struct Monsters{
	ll a,b,res;
	bool operator < (const Monsters&mon) const{return a<mon.a;}
}m[maxn];
int main()
{
	close;int T;cin>>T;
	while(T--)
	{
		ll A,B,n;cin>>A>>B>>n;
		for(int i=1;i<=n;++i) cin>>m[i].a;
		for(int i=1;i<=n;++i) cin>>m[i].b;
		int pos;sort(m+1,m+n+1);
		for(int i=1;i<=n;++i)
		{
			pos=i;
			ll h=(B/m[i].a)+(B%m[i].a!=0?1:0),l=(m[i].b/A)+(m[i].b%A!=0?1:0),r=min(h,l);
			B-=m[i].a*r;m[i].b-=A*r;
			if(B<=0) break;
		}
		if(pos<n) cout<<"NO\n";
		else if(pos==n){
			if(m[n].b<=0) cout<<"YES\n";
			else cout<<"NO\n";
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

C:Searching Local Minimum

  这是一道交互式问题,题目大意是只给定一个 n n n(告诉你原序列是一个1~n的全排列中的一种),然后你的程序不断询问某个下标的值(最多不能超过100次询问),最后给出一个下标,满足 a i < m i n ( a i − 1 , a i + 1 ) a_i<min(a_{i-1},a_{i+1}) ai<min(ai1,ai+1)
  二分三分都是可以的,我这里采用的是三分法,虽然整个图像并不是一个完全的单峰函数,但题目也没要求输出全局最小值,因此通过三分法一定能够找到一个局部的单峰性质,也就能输出最小值。使用三分法需要严格注意自己输出的下标的值是否合法,最后的值是否正确(可能会因为写法不同造成偏移)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
int main()
{
	int n;cin>>n;
	int l=0,r=n+1,x1,x2;
	while(l+1<r){
		int mid=(l+r)/2;
		cout<<"? "<<mid<<endl;fflush(stdout);
		cin>>x1;
		int midd=(mid+r)/2;
		cout<<"? "<<midd<<endl;fflush(stdout);
		cin>>x2;
		if(x1<x2) r=midd;
		else l=mid;
	}
	cout<<"! "<<l<<endl;fflush(stdout);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

D1:Painting the Array I

  题目大意是定义了一种运算 s e g seg seg,代表将一个序列中连续相同的一段仅保留其中一个后,新序列的元素个数。然后给定你一个原序列A,你需要找到一个子序列 a 0 a^0 a0 a 1 = A − a 0 a^1=A-a^0 a1=Aa0,问 m a x { s e g ( a 0 ) + ( a 1 ) } max\{seg(a^0)+(a^1)\} max{seg(a0)+(a1)}.
  贪心了一个小时都没贪出来的菜狗,而且这种前面的选择会影响后续的我断然不敢往贪心上面猜,但这个世界就是这么的奇妙
  使用贪心的策略,我们令 l a s t 1 , l a s t 2 last1,last2 last1,last2分别代表前两个序列的最后一个字符,现在来考虑第 i i i个字符:① l a s t 1 = = l a s t 2 last1==last2 last1==last2时, s [ i ] s[i] s[i]放在哪个序列后面都无所谓;② l a s t 1 = = s [ i ]   & &   l a s t 2 ≠ s [ i ] last1==s[i]\ \&\& \ last2\ne s[i] last1==s[i] && last2=s[i]时,直接放在序列2后就能得到最优解;③ l a s t 2 = = s [ i ]   & &   l a s t 1 ≠ s [ i ] last2==s[i]\ \&\& \ last1\ne s[i] last2==s[i] && last1=s[i]时,直接放在序列1后就能得到最优解;④ l a s t 1 ≠ s [ i ]   & &   l a s t 2 ≠ s [ i ] last1\ne s[i]\ \&\& \ last2\ne s[i] last1=s[i] && last2=s[i]时,定义 n e x t [ x ] next[x] next[x]表示 x x x在第 i i i个元素后的下一个出现位置,比较 n e x t [ l a s t 1 ] next[last1] next[last1] n e x t [ l a s t 2 ] next[last2] next[last2],谁小放在谁后。

#include<bits/stdc++.h>
#define close ios::sync_with_stdio(false)
using namespace std;
const int maxn=1e5+100;
int a[maxn],ind[maxn];
vector<int> v[maxn];
int main()
{
	close;int n;cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i],v[a[i]].push_back(i);
	int last1=0,last2=0,ans=0;
	for(int i=1;i<=n;++i)
	{
		ind[a[i]]++;
		if(last1==last2){
			if(last1!=a[i]) last1=a[i],ans++;
		}
		else if(last1==a[i] && last2!=a[i]) last2=a[i],ans++;
		else if(last2==a[i] && last1!=a[i]) last1=a[i],ans++;
		else{
			ans++;
			int next1=n+1,next2=n+1;
			if(ind[last1]<v[last1].size()) next1=v[last1][ind[last1]];
			if(ind[last2]<v[last2].size()) next2=v[last2][ind[last2]];
			if(next1<next2) last1=a[i];
			else last2=a[i];
		}
	}
	cout<<ans;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

D2:Painting the Array II

  题目大意和上述题目相同,仅仅是询问 m i n { s e g ( a 0 ) + ( a 1 ) } min\{seg(a^0)+(a^1)\} min{seg(a0)+(a1)}.
  使用贪心的策略,我们令 l a s t 1 , l a s t 2 last1,last2 last1,last2分别代表前两个序列的最后一个字符,现在来考虑第 i i i个字符:① l a s t 1 = = l a s t 2 last1==last2 last1==last2时, s [ i ] s[i] s[i]放在哪个序列后面都无所谓;② l a s t 1 = = s [ i ]   & &   l a s t 2 ≠ s [ i ] last1==s[i]\ \&\& \ last2\ne s[i] last1==s[i] && last2=s[i]时,直接放在序列1后就能得到最优解;③ l a s t 2 = = s [ i ]   & &   l a s t 1 ≠ s [ i ] last2==s[i]\ \&\& \ last1\ne s[i] last2==s[i] && last1=s[i]时,直接放在序列2后就能得到最优解;④ l a s t 1 ≠ s [ i ]   & &   l a s t 2 ≠ s [ i ] last1\ne s[i]\ \&\& \ last2\ne s[i] last1=s[i] && last2=s[i]时,定义 n e x t [ x ] next[x] next[x]表示 x x x在第 i i i个元素后的下一个出现位置,比较 n e x t [ l a s t 1 ] next[last1] next[last1] n e x t [ l a s t 2 ] next[last2] next[last2],谁小放在另一个后。

#include<bits/stdc++.h>
#define close ios::sync_with_stdio(false)
using namespace std;
const int maxn=1e5+100;
int a[maxn],ind[maxn];
vector<int> v[maxn];
int main()
{
	close;int n;cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i],v[a[i]].push_back(i);
	int last1=0,last2=0,ans=0;
	for(int i=1;i<=n;++i)
	{
		ind[a[i]]++;
		if(last1==last2){
			if(last1!=a[i]) last1=a[i],ans++;
		}
		else if(last1==a[i] && last2!=a[i]) continue;
		else if(last2==a[i] && last1!=a[i]) continue;
		else{
			ans++;
			int next1=n+1,next2=n+1;
			if(ind[last1]<v[last1].size()) next1=v[last1][ind[last1]];
			if(ind[last2]<v[last2].size()) next2=v[last2][ind[last2]];
			if(next1<next2) last2=a[i];
			else last1=a[i];
		}
	}
	cout<<ans;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

E:Continuous City

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/75051
推荐阅读
相关标签
  

闽ICP备14008679号