Codeforces Round 927 (Div. 3) A--E

A. Thorns and Coins

题目链接

题意

长度为n的字符串,其中@表示金币,*表示荆棘,每次可以移动1个或2个长度,不可以走到有荆棘的位置上,求可以获得金币的最大数量

分析

在遇到连续的两个荆棘前,我们可以一直收集金币,枚举即可

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
//#include<queue>
//#include<map>
//#include<vector>
//#include<set>
//#include<deque>
//#include<bitset>
//#include<functional>
 
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
 
typedef pair<int,int>PII;
 
void solve()
{
	int n;
	string s;
	cin>>n>>s;
	ll ans=0;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='*' && s[i+1]=='*') break;
		if(s[i]=='@') ans++;
	}
	cout<<ans<<endl;
	
}	
	
int main()
{
	int t;cin>>t;
	while(t--) solve();
	
	
	return 0;
}

B. Chaya Calendar

题目链接

题意

有n个符号,第i个符号每隔a[i]年出现一次,如果第i个符号出现在第x年,那么第i+1个符号只能出现在x年之后(每年只能接收一个符号),求接收全部符号发生在第几年

分析

由于每个符号循环出现,而且每年只能接受一个符号,分情况讨论

1.下一个符号出现的年份在上一个符号出现年份之后

此时只需要等待到下一个符号出现的年份即可

2.下一个符号出现的年份在上一个符号出现年份之前

那么需要等待到k*a[i+1]年,其中k代表满足k*a[i+1]>a[i]成立的最小的k,二分出最小的k即可

分情况计算出现年份,不断更新上一个符号出现年份即可

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
//#include<queue>
#include<stack>
//#include<set>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
using namespace std;

typedef pair<int,int>PII;
void solve()
{
	int n;cin>>n;
	vector<ll>f(n+1);
	for(int i=1;i<=n;i++) cin>>f[i];
	ll last=f[1];
	for(int i=2;i<=n;i++)
	{
		if(f[i]<=last+1)
		{
			int l=0,r=1e9;
			while(l+1<r)
			{
				int mid=(l+r)>>1;
				if(mid*f[i]<=last) l=mid;
				else r=mid;
			}
			last=r*f[i];
		}
		last=max(last,f[i]);
	}
	cout<<last<<endl;
}

	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--) solve();
	
	return 0;
}

C. LR-remainders

题目链接

题意

您将得到一个长度为 n的数组 a 、一个正整数 m 和一个长度为 n的命令字符串。每个命令都是字符“L”或字符“R”。

按照在字符串 s 中写入命令的顺序处理所有 n 命令。

命令的处理过程如下:

-首先,输出数组 a 的所有元素的乘积除以 m 的余数。

-然后,如果命令是'L',则从数组 a 中删除最左边的元素,如果命令是'R',

从数组 a中删除最右边的元素。请注意,每次移动后,数组 a的长度将减少 1 ,并且在处理所有命令后,它将为空。

分析

t最大为1e4,n最大为2e5,a[i]最大为1e4,如果直接将数组元素全部乘起来操作会爆int,如果开long long(从wa2变成了wa3)也会爆,考虑高精度(可能会tle),也可以逆向思维,倒过来做,由于已知删除顺序,我们从最后一个删除的数开始,不断还原原数组此时的乘积,然后将答案存入答案数组中,最后倒序输出即可

由于是倒序操作,可以使用stack方便存储

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
//#include<queue>
#include<stack>
//#include<set>
//#include<deque>
//#include<bitset>
//#include<functional>
 
#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
using namespace std;
 
typedef pair<int,int>PII;
 
void solve()
{
	int n,m;cin>>n>>m;
	vector<int>f(n+1);
	for(int i=1;i<=n;i++) cin>>f[i];
	string s;cin>>s;
	stack<int>sta;
	int l=1,r=n;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='L') sta.push(f[l++]);
		else sta.push(f[r--]);
	}
	vector<ll>ans(n+1);
	ll t=1;
	for(int i=n;i>=1;i--)
	{
		t=t*sta.top()%m;
		sta.pop();
		ans[i]=t;
	}
	for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
	cout<<endl;
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--) solve();
	
	return 0;
}

D. Card Game

题目链接

题意

有四种花色的卡牌,分别用C,S,D,H代表,每种花色有2-9八张,四种花色共有32张卡牌,每局游戏给出一种花色作为王牌花色,每轮游戏第一个人打出一张卡牌,第二个人只能打出比他大的卡牌,该轮结束,关于卡牌大小规定如下

1.相同花色时,数字越大的卡牌越大

2.王牌花色卡牌比其他卡牌大,不论点数是多少

3.王牌花色卡牌比较时,点数大的卡牌大

现给定n,代表该场游戏已经进行多少轮,和王牌花色,以及2*n张卡牌代表其花色和点数,如果存在合理的游戏回合,输出每轮两人打出的卡牌,若不存在输出IMPOSSIBLE

分析

最讨厌模拟的一集,由于相同卡牌花色点数唯一,所以当相同花色卡牌出现2张时,一定可以消掉,我们可以用map记录每种花色上次出现的点数,当有花色出现两次时,将其调整为小点数在前大点数在后的格式加入ans中,将王牌花色卡牌的点数单独加入一个容器中。此操作结束之后,除去王牌花色,其余花色最多只剩一张牌没有消去,如果此时王牌花色的牌数小于其余花色的牌数,那么该轮不合理,输出impossible,否则我们将王牌花色的牌按点数从小到大排序,将其余花色的牌用王牌花色消去后加入ans,剩下的王牌花色牌分别消去加入ans即可

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
//#include<queue>
#include<stack>
#include<set>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;char king;
	cin>>n>>king;
	vector<int>v;
	vector<string>ans;
	n*=2;
	map<char,int>mp;
	for(int i=1;i<=n;i++)
	{
		string s;cin>>s;
		if(s[1]==king) v.emplace_back(s[0]-'0');
		else
		{
			string ss=s;
			if(mp[ss[1]])
			{
				s+=" ";
				//cout<<s<<endl;
				s+=mp[ss[1]]+'0';
				//cout<<s<<endl;
				s+=ss[1];
				//cout<<s<<endl;
				if(s[0]>s[3]) swap(s[0],s[3]);
				ans.emplace_back(s);
				mp[ss[1]]=0;
				
			}
			else mp[ss[1]]=ss[0]-'0';
		}
	}
	ll res=0;
	if(mp['C']!=0) res++;
	if(mp['S']!=0) res++;
	if(mp['D']!=0) res++;
	if(mp['H']!=0) res++;
	//cout<<res;
	
	if(v.size()<res)
	{
		cout<<"IMPOSSIBLE"<<'\n';
		return;
	}
	sort(v.begin(),v.end());
    //for(auto c:ans) cout<<c<<" ";
    string t;
    for(auto c:v)
    {
    	if(mp['S']!=0 || mp['C']!=0 || mp['D']!=0 || mp['H']!=0)
    	{
    		
    	    if(mp['C']!=0 && t.size()<2) t+=mp['C']+'0',t+='C',mp['C']=0;
    	    else if(mp['S']!=0 && t.size()<2) t+=mp['S']+'0',t+='S',mp['S']=0;
    	    else if(mp['D']!=0 && t.size()<2) t+=mp['D']+'0',t+='D',mp['D']=0;
    	    else if(mp['H']!=0 && t.size()<2) t+=mp['H']+'0',t+='H',mp['H']=0;
    	    //cout<<t<<endl;
    		t+=" ";
    		t+=c+'0';
    		t+=king;
    		ans.emplace_back(t);
    		t="";
    	}
    	else
    	{
    		t+=c+'0';
    		t+=king;
    		if(t.size()==2) t+=" ";
    		if(t.size()==5)
    		{
    			ans.emplace_back(t);
    			t="";
    		}
    		
    	}
    	
     }
     for(auto c:ans) cout<<c<<endl;
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--) solve();
	
	return 0;
}

E. Final Countdown

题目链接

题意

给定一个长度为n的整数a,a每次减少1要经过t秒,t为a变为a-1所改变的位数,例100变为99需要2秒,因为其改变了两位;1100变为1099需要3秒,求当a减少为0时,需要经过多少秒

分析

最不会数学的一集,结论是12345需要12345+1234+123+12+1秒,1234需要1234+123+12+1秒,每次除10相加,直到为0,由于n最大为4e5,需要高精度,观察可以发现每一位数只加其前面的数,

例如

12345
 1234
  123
   12
    1

我们可以使用前缀和数组记录每一位数加完之后的结果,然后倒序模拟进位,在输出时过滤掉前导0即可

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
//#include<queue>
#include<stack>
//#include<set>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	string s;cin>>s;
	s=" "+s;
	vector<ll>pre(n+1);
	for(int i=1;i<=n;i++) pre[i]=pre[i-1]+s[i]-'0';
	
	for(int i=n;i>=0;i--)
	{
		pre[i-1]+=pre[i]/10;
		pre[i]=pre[i]%10;
		//cout<<pre[i];
	}
	int flag=0;
	for(int i=0;i<=n;i++)
	{
		//cout<<pre[i];
		if(pre[i]!=0) flag=1;
		if(flag) cout<<pre[i];
	}
	cout<<endl;
	
}

	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--) solve();
	
	return 0;
}

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值