Educational Codeforces Round 153 (Rated for Div. 2) A - C

 

A.Not a Substring

题意:

定义正规括号对为“()”、“()()”、“(())”此类的可以匹配的括号对,如”)(“是不正则的,现在输入给你一个指定括号序列,询问你是否能构造出一个两倍长度的括号序列,做到构造括号序列不包含所给括号序列。s为所给括号序列长度

 

分析:

将‘(’视作1,‘)’视作0,发现如果括号序列不严格单调递减,即类似于“(((())”=111100,那就可以构造为“()()()()()()”,若不为不严格单调序列,即类似于“())(”=1001,那就构造为“(((())))”

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

void solve()
{
	string s;
	cin>>s;
	int n=s.length();
	int a[n];
	if(s=="()")
	{
		cout<<"NO"<<endl;
		return ;
	}
	else 
	{
		cout<<"YES"<<endl;
	}
	for(int i=0;i<n;i++)
	{
		if(s[i]=='(')a[i]=1;
		else a[i]=0;
	 } 
	bool flag=0;
	for(int i=0;i<n-1;i++)
	{
		if(a[i]<a[i+1])
		{
			flag=1;
			break; 
		}
	}
	if(flag==0)
	{
		for(int i=0;i<2*n;i++)
		{
			if(i%2==0)cout<<'(';
			else cout<<')';
		}
		cout<<endl;
	}
	else
	{
		for(int i=0;i<n;i++)
		{
			cout<<'(';
		}
		for(int i=0;i<n;i++)
		{
			cout<<')';
		}
		cout<<endl;
	}
}
signed main()
{
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}
 

 

B.Fancy Coins

题意:

有一件价值m的商品,Monocarp想买它,Monocarp有两种硬币,一种面值为1(有a1个),一种面值为k(有ak个);Monocarp只会用刚好m元的价格购买这个商品。题目告诉我们m,k,a1,ak;问我们还额外需要几个硬币才能购买这个商品

39826b052d7f4a01abe5745898d10822.png

 

分析:

我们的想法肯定是如果能面值为k的硬币的话就用它(即总钱数没超过m且硬币数量够),换言之我们要尽量多的使用面值为k的硬币,然后再用面值为1的硬币补上缺口,从这里我们分类讨论,下面用if else来写hhh

if(已有的面值为k的硬币数量大于等于最大需要的数量)//这里指的是我们最大需要多少个,即需要m/k个

{

       if(已有的面值为1硬币数量大于等于最小需要的数量)//最小需要多少个,即为m%k,也就是         m-m/k

      {

                输出0,因为都已经满足 }

        else //已有的面值为1硬币数量小于最小需要的数量

        {

                输出面值为1的硬币缺少的数量

         }

}

else //已有的面值为k的硬币数量小最大需要的数量 就是说我们的k面值的硬币不够

{

         if(已有的面值为1硬币数量大于等于最小需要的数量)面值为1的硬币有多,可以尽量去替换缺少的面值为k的硬币

        {

                输出(面值为k的硬币缺少的个数 - (面值为1的硬币多出来的个数/k))

        }

        else //面值为1的硬币也不够

        {

                输出(面值为1的硬币缺少的数量 + 面值为1的硬币缺少的数量)

        }

}

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

void solve()
{
	
	int m,k,a,b;
	cin>>m>>k>>a>>b;
	int z=0; 
	if((m/k-b)<=0)
	{
		if((a-(m%k))>=0)
		{
			cout<<"0"<<endl;
		}
		else
		{
			cout<<(m%k)-a<<endl;
		}
	}
	else
	{
		if((a-(m%k))>=0)
		{
			cout<<max(z,(m/k-b)-(a-(m%k))/k)<<endl;
		}
		else 
		{
			cout<<max(z,(m/k-b)+(m%k)-a)<<endl;
		}
	}
	
}

signed main()
{
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}
 
 

 

C. Game on Permutation

题意:

爱丽丝和鲍勃轮流走同一个棋子,棋盘是一个条形的(输入的一个数组),上面的数字对应了这个位置的值。其中爱丽丝走第一步并且第一步只能放置棋子而不能移动棋子,每次移动只能将棋子移动到当前位置的左边且数值比当前位置数值小的地方,比如213,3可以移动到2或者1,1不可以移动到2因为2比1大。如果谁先不能移动,谁就赢了。如果对于一个位置,爱丽丝先将棋子放在这里,她一定可以获胜,则我们称这个位置为必胜位置,请输出必胜位置的个数。

分析:

用常用的思维考虑,对于必胜的情况,我们尝试着去思考必败的情况再找反之的条件,我们首先研究,怎么样会让对方赢,那么当左边没有可选数字时,或者对方下一步走到必胜状态时,他就赢了,那么反之思考我们获胜的条件就是左边有可选数字并且对方下一步无法走到必胜状态,我们就必胜了。那么我们只需要记录左边可选数字的最小值,和左边必胜状态的最小值就可以了,(因为如果连最小的都走不了,那肯定没法走了),通过一个for循环找到必胜位置的个数

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

void solve()
{
	int n;
	cin>>n;
	int a[n];
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	int x=1e9+10,y=a[0],ans=0;
        //x记录当前数左边最小必胜状态的值,y记录当前数左边最小可选数的值
	for(int i=1;i<n;i++)
	{
		if(a[i]>y&&a[i]<x)//必胜情况 ,a[i] > y 表示左边有可选状态,a[i] < x 表示左边无可走的必胜状态
		{
			x=min(x,a[i]);//x表示前面可以转移的最小必胜状态值 
			ans++;
		}
		y=min(y,a[i]);//y表示前面可以转移的最小值 
	}
	cout<<ans<<endl; 
	
	
}

signed main()
{
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}

CSDN:陪你一起cf

bilibili:acmer--沈幼楚

知乎:与你cf

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值