Codeforces Round 964 (Div. 4)B,E

B. Card Gameicon-default.png?t=N7T8https://codeforces.com/contest/1999/problem/B

B. Card Game

这题在前四题感觉最难。首先看好题意,要所有翻开来的可能有四种(a1,a2,b1,b2两两组合)这里直接列举就行,反正数量就四个。每一种看看能否赢,而赢的话注意:需要两对全赢或者有一对平局了,然后另一对赢了。

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef long long ll;
int fan(int a1,int a2,int b1,int b2)
{
	if(a1>b1&&a2>=b2)return 1;
	if(a1>=b1&&a2>b2)return 1;
	else return 0;
}
void solve() {
	int cnt;int a[2],b[2];cin>>a[0]>>a[1]>>b[0]>>b[1];
    int s1=fan(a[0],a[1],b[0],b[1]);
	int s2=fan(a[0],a[1],b[1],b[0]);
	int s3=fan(a[1],a[0],b[0],b[1]);
	int s4=fan(a[1],a[0],b[1],b[0]);
	cnt=s1+s2+s3+s4;
	cout<<cnt<<endl;
   
   
}
int main(){
    int T;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

E. Triple Operationsicon-default.png?t=N7T8https://codeforces.com/contest/1999/problem/E

E. Triple Operations

拿前缀和和直接/3计数放数组里都可以,只是要把这个提前做好不然肯定TLE,就是放在外面,不能能放在循环里面。

思路:首先把最小的给弄成0,然后再用这个0跟其他的值去操作,慢慢的别的也会变成0,而操作数是:首先的最小的数变0的次数(a1/3一直处到0的cnt)再加上所有数组里面的数/3的cnt,最小的那个也算在里面的,原因是把这个最小的变成0,一定也要有个其他的数*3,相当于把这个最小的a1算在别人头上了,所以是全体数组的数的cnt,当然可以在最开始算a1的cnt循环的时候直接cnt+=2。这是第一种代码思路。(代码块1

还有种改良版(也不能算改良因为都差不多)前缀和解法:基于上面那种,但是把在solve()里面的一个循环优化掉了,直接在外面做一个前缀和计算前k个cnt的和然后进solve了之后直接ps[l]-ps[r-1]即可,无需第一种方案的循环l到r去累加,稍微快点。(代码块2

代码块1:

#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
typedef long long ll;
int sm[N];
void solve() {
	int l,r;cin>>l>>r;int x=l,cnt=0;
	while(x)
	{x/=3;cnt+=2;}
	
	for(int i=l+1;i<=r;i++)
	{
		cnt+=sm[i];
	}
	cout<<cnt<<endl;
}
int main(){
    int T;cin >> T;
    sm[0]=1;sm[1]=1;sm[2]=1;
	for(int i=3;i<N;i++)
	{
		sm[i]=sm[i/3]+1;
	}
    while(T--){
        solve();
    }
    return 0;
}

代码块2:

#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
typedef long long ll;
int sm[N],ps[N];
void solve() {
	int l,r;cin>>l>>r;int x=l,cnt=0;
	while(x)
	{x/=3;cnt+=1;}
	cnt+=ps[r]-ps[l-1];
	cout<<cnt<<endl;
}
int main(){
    int T;cin >> T;
    sm[0]=1;sm[1]=1;sm[2]=1;
	for(int i=3;i<N;i++)
	{
		sm[i]=sm[i/3]+1;
	}
	ps[1]=1;ps[0]=0;
	for(int i=2;i<=N;i++)
	{
		ps[i]=ps[i-1]+sm[i];
	}
    while(T--){
        solve();
    }
    return 0;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值