A.水盐平衡
数学。签到题,可以直接计算浓度并进行比较,也可以转化为a*d与b*c的比较。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int a[N];
void solve(){
int a,b,c,d;cin>>a>>b>>c>>d;
if((a*d)>(b*c)){
cout<<"S"<<endl;
}
else{
cout<<"Y"<<endl;
}
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
B.水平考试
模拟。读入字符串后,首先特判字符串,若S比F的长度长,不用想肯定为0分。注意本题题意说明只可多不可少,因此不可能出现得5分的情况。故只需要判断A、B、C、D在两个字符串中出现的次数即可。(记得初始化!赛时因为这个wa了3发ToT)
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int n1[4],n2[4];
void solve(){
string S;cin>>S;
string F;cin>>F;
int ans=0;
if(S.size()>F.size()){
cout<<"0"<<endl;
return;
}
for(int i=0;i<S.size();i++){
n1[S[i]-'A']++;
}
for(int i=0;i<F.size();i++){
n2[F[i]-'A']++;
}
for(int i=0;i<4;i++){
if(n1[i]==1&&n2[i]==0){
cout<<"0"<<endl;
return;
}
}
cout<<"10"<<endl;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
C.数组段数
前缀和。题意相当简单,朴素做法即在询问区间中元素相同(题意中即数字相同)的子串分为一段即可。为了防止TLE,用前缀和处理一遍即可。处理思路:用b数组记录原数组总共可以分为几段。注意到相同元素会分为同一段,可以得出:当前元素与前一个元素相同时,则这两个元素划分在同一段。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int a[N],b[N];
void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
b[1]=1;
for(int i=2;i<=n;i++){
if(a[i-1]==a[i]) b[i]=b[i-1];
else{
b[i]=b[i-1]+1;
}
}
while(m--){
int l,r;cin>>l>>r;
if(l==r){
cout<<"1"<<endl;
continue;
}
cout<<b[r]-b[l]+1<<endl;
}
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
D.剪纸游戏
DFS(深度优先搜索)。这题实现过程不难,主要是判断是否为矩形有一定难度。可以发现,若剪出来的区域为矩形,此时数出来的“.”的数量与该区域的横坐标覆盖区间与纵坐标覆盖区间之积相同。而为了数出“.”的数量则采用DFS。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1010;
char a[1010][1010];
int n,m;
int cnt;
int mxx,mxy,mnx,mny;
int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0};
void dfs(int x,int y){
a[x][y]='*';
cnt++;
mxx=max(mxx,x);
mnx=min(mnx,x);
mxy=max(mxy,y);
mny=min(mny,y);
for(int i=0;i<4;i++){
int tx=x+dx[i];
int ty=y+dy[i];
if(tx>=0&&ty>=0&&tx<n&&ty<m&&a[tx][ty]=='.'){
dfs(tx,ty);
}
}
}
void solve(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
}
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='.'){
mxx=0;mnx=n;mxy=0;mny=m;
cnt=0;
dfs(i,j);
if(cnt==(mxx-mnx+1)*(mxy-mny+1)) ans++;
}
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
E.可口蛋糕
思维,前缀和,双指针。参考了榜一大佬的代码,该题主要难点在于如何优化时间复杂度,可以用前缀和预处理。处理思路:将饱腹度与可口度都求前缀和,接着用双指针去寻找最大合法区间(即满足饱腹度的区间值),再找出合法区间的可口度最大值即可。该题思维难度较高。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e6+5;
int a[N],b[N];
void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=a[i-1];
}
for(int i=1;i<=n;i++){
cin>>b[i];
b[i]+=b[i-1];
}
int j=0,res=1e18,ans=-1e18;
for(int i=1;i<=n;i++){
while(a[i]-a[j]>=m){
res=min(res,b[j]);
j++;
}
ans=max(ans,b[i]-res);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}