B. Card Gamehttps://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 Operationshttps://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;
}