签到题A~C
A
#include<bits/stdc++.h>
using namespace std;
int n,w,x,y;int a[100005],b[100005];
int main()
{
int T=1;cin>>T;
while(T--){
cin>>w>>x>>y;
if(w==x+y)cout<<"YES\n";
else if(x==w+y)cout<<"YES\n";
else if(y==x+w)cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
int n,w,x,y;int a[100005],b[100005];
int main()
{
int T=1;cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);bool flag=0;
for(int i=1;i<n;i++)
if(a[i]==a[i+1])flag=1;
if(flag)cout<<"NO\n";
else cout<<"YES\n";
}
return 0;
}
C
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T=1;cin>>T;
while(T--){
int n,w,x,y;int a[10]={0},b[10]={0};char mp[10][10];
for(int j=1;j<=8;j++)
for(int i=1;i<=8;i++)cin>>mp[j][i];
for(int ii=1;ii<=8;ii++){
bool flag=0;
for(int i=1;i<=8;i++){
if(mp[ii][i]!='R')flag=1;
}
if(!flag)a[ii]=1;
}
for(int ii=1;ii<=8;ii++){
bool flag=0;
for(int i=1;i<=8;i++){
if(mp[i][ii]!='B')flag=1;
}
if(!flag)b[ii]=1;
}
for(int i=1;i<=8;i++){
if(a[i]){cout<<"R\n";break;}
if(b[i]){cout<<"B\n";break;}
}
}
return 0;
}
D. Coprime
题意:给一个数列,如果a[i]和a[j]互质,那么i+j。求最大的i+j
错误:比赛的时候我把所有答案都存在vector里面了,结果MLE了,回过神来发现只要max就可以了,结果因为n平方的复杂度TLE了
思路:赛后发现虽然n有2e5,但是a的范围只有1~1000,所以可以记录下每个a[i]的最大序号,在循环1e6次就能做完了
代码:
#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};int n;int vis[1003];
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
int T=1;cin>>T;
while(T--){
memset(vis,0,sizeof(vis)); int maxx=-1;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)vis[a[i]]=i;
for(int i=1;i<=1000;i++){
for(int j=i;j<=1000;j++){
if(!vis[i]||!vis[j])continue;
if(__gcd(i,j)==1)maxx=max(maxx,vis[i]+vis[j]);
}
}
cout<<maxx<<'\n';
}
return 0;
}
E. Scuza
题意:已知腿长,走楼梯,直到楼梯高度大于腿长,不走了,求已经走过的高度
扫描二维码关注公众号,回复:
15892280 查看本文章
错误:比赛的时候写双重循环,TLE了;想到了前缀和,没有想过前缀最大值;想过了二分查找,但觉得没有次序就没接着想了
思路:前缀最大值+二分查找
lower_bound() 函数查找[first, last)区域中不小于val的第一个元素。
upper_bound() 查找[first, last)区域中第一个大于 val 的元素。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,w,x,y;int a[200005],k,sum[200005],maxx[200005]={0};
signed main()
{
int T=1;cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];sum[i]=sum[i-1]+a[i];maxx[i]=max(maxx[i-1],a[i]);
}
for(int i=1;i<=m;i++){
cin>>k;
int x=upper_bound(maxx+1,maxx+n+1,k)-maxx;
cout<<sum[x-1]<<' ';
}
cout<<'\n';
}
return 0;
}
F. Smaller
读错题了orz 反正就是挺简单的一道题
记得开long long
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,w,x,y;
signed main()
{
int T=1;cin>>T;
while(T--){
cin>>n;int suma=1,sumb=1;int a=1,b=1;
for(int i=1;i<=n;i++){
int d,k;cin>>d>>k;string ss;cin>>ss;
if(d==1)for(int p=0;p<ss.size();p++)if(ss[p]=='a')a+=k,suma+=k;
if(d==2)for(int p=0;p<ss.size();p++)if(ss[p]=='a')b+=k,sumb+=k;
if(b!=sumb)cout<<"YES\n";
else if(a==suma){
if(suma<sumb)cout<<"YES\n";
else cout<<"NO\n";
}
else cout<<"NO\n";
//a和b都是a,但是a的个数比b少
//a不都是a,但b都是a,失败
//b不都是a,成功
}
}
return 0;
}
G. Orray
做的时候总是习惯把数字拆开来做,但好像这种题都是找一个数异或 or 或,然后看情况做
思路:把所有数都遍历一遍,最后找到最优的结果输出
注意:如果把a|b放在if的条件里判断大小,记得加括号
代码:
#include<bits/stdc++.h>
using namespace std;
int a[200005];
bool vis[200005];
int main()
{
int T;cin>>T;
while(T--){
memset(vis,0,sizeof(vis));
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int now=0,mx=0;
for(int i=1;i<=min(31,n);i++){
int id=0;
for(int j=1;j<=n;j++){
if((now|a[j])>mx){
mx=now|a[j];id=j;
}
}
if(id==0)break;
now=mx;vis[id]=1;cout<<a[id]<<' ';
}
for(int i=1;i<=n;i++){
if(vis[i]==0)cout<<a[i]<<' ';
}
cout<<'\n';
}
return 0;
}