A
题记:首先判断四个数相加能否被三整除,然后判断a,b,c当中有没有大于平均数。满足条件输出YES,否则输出NO。
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
typedef long long ll;
int main(){
int t;
cin>>t;
int a,b,c,n;
while(t--){
cin>>a>>b>>c>>n;
int sum=a+b+c+n;
if(sum%3==0){
sum/=3;
if(a<=sum&&b<=sum&&c<=sum){
cout<<"YES"<<endl;
continue;
}
}
cout<<"NO"<<endl;
}
return 0;
}
B
题记:由于机器人智能向右或者向上走,所以按照横坐标从小到大排序,横坐标一样的按照纵坐标从小到大排序。之后遍历用nx,ny记录当前位置,如果有y比ny小的情况就输出NO。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
typedef long long ll;
struct node{
int dx,dy;
};
bool cmp(node a,node b){
if(a.dx==b.dx)
return a.dy<b.dy;
return a.dx<b.dx;
}
int main(){
int t;
cin>>t;
int n,x,y;
while(t--){
cin>>n;
node node[N];
for(int i=0;i<n;i++){
cin>>x>>y;
node[i].dx=x;
node[i].dy=y;
}
sort(node,node+n,cmp);
string s;
int nx=0,ny=0,flag=1;
for(int i=0;i<n;i++){
if(node[i].dy<ny){
cout<<"NO"<<endl;
flag=0;
break;
}
for(int j=nx;j<node[i].dx;j++)
s+='R';
nx=node[i].dx;
for(int j=ny;j<node[i].dy;j++)
s+='U';
ny=node[i].dy;
}
if(flag){
cout<<"YES"<<endl;
cout<<s<<endl;
}
}
return 0;
}
C
题解:枚举n的因子,判断因子能否再继续分解。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
while(n--){
int x;
vector<int>a;
cin>>x;
int cnt=0;
for(int i=2;i*i<=x;i++){
if(x%i==0){
cnt++;
x/=i;
a.push_back(i);
}
if(cnt==3)
break;
}
if(x!=1){
if(a.size()==3)
a.back()*=x;
else
a.push_back(x);
}
if(a.size()<3||a[0]==a[1]||a[0]==a[2]||a[1]==a[2])
cout<<"NO"<<endl;
else
cout<<"YES"<<endl<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
}
return 0;
}
D
题记:可以把输入数组分为很多个长度为x的片段,每一段的数无论是加x还是减x这个数余x的值是不变的,所以每输入一个数就用数组a存下这个数余x的值。sum记录当前的最小正整数,当a[sum%x]不为0时sum++,否则退出循环,把每次遍历的sum存入ans数组,最后输出即可。
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
typedef long long ll;
int a[N],ans[N];
int main(){
int q,x;
cin>>q>>x;
int n,sum=0;
for(int i=0;i<q;i++){
cin>>n;
a[n%x]++;
while(a[sum%x]){
a[sum%x]--;
sum++;
}
ans[i]=sum;
}
for(int i=0;i<q;i++)
cout<<ans[i]<<endl;
return 0;
}
E
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int N=2e5+5;
vector<int>a[N];
int cnt[N];
int main(){
int n,m,x;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&x);
a[i].push_back(--x);
//输入的数需要减一,方便后面计算
}
}
int ans=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)cnt[j]=n+j;
for(int j=0;j<n;j++){
if(a[j][i]%m==i&&a[j][i]/m<n){
int sum=a[j][i]/m;
cnt[((j+n-sum)%n)]--;
}
}
int num=INF;
for(int j=0;j<n;j++)num=min(num,cnt[j]);
ans+=num;
}
cout<<ans<<endl;
return 0;
}
F
题记:找出每次bfs可以走最远的哪个数,bfs三次即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
vector<int>a[maxn];
int n,vis[maxn],dis1[maxn],dis2[maxn],dis[maxn],pos;
void bfs(int x){//把bfs模板套进去即可
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
pos=x;
vis[x]=1;//标记起点,相当于已经走过了
//dis[x]=0;
queue<int>q;
q.push(x);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<a[u].size();i++){//a[u].size()表示u这个数一共链接几个数
if(!vis[a[u][i]]){//当这个数没有走过
vis[a[u][i]]=1;//标记这个数已经走过
dis[a[u][i]]=dis[u]+1;//从起点到这个数一共走了几步
q.push(a[u][i]);//入列
if(dis[a[u][i]]>dis[pos])//
pos=a[u][i];//记录能走到最远的点
}
}
}
}
int main(){
cin>>n;
int u,v;
for(int i=1;i<n;i++){
cin>>u>>v;
a[u].push_back(v);//记录u这个数可以通向v
a[v].push_back(u);//记录v这个数可以通向u
}
int a,b,c;
bfs(1);
a=pos;
bfs(pos);
b=pos;
for(int i=1;i<=n;i++){
//cout<<dis[i]<<" ";
dis1[i]=dis[i];//记录从a走到i需要多少步,即这两个数之间有多少个并集
}
//cout<<endl;
bfs(pos);
for(int i=1;i<=n;i++){
//cout<<dis[i]<<" ";
dis2[i]=dis[i];//记录从b走到i需要多少步,即这两个数之间有多少个并集
}
c=0;//c从0开始
for(int i=1;i<=n;i++){
if(dis1[i]+dis2[i]>dis1[c]+dis[c]&&i!=a&&i!=b)//选一个从a走到c加上b走到c步数最多的c
c=i;
}
cout<<dis1[b]<<" "<<dis1[c]<<" "<<dis2[c]<<endl;
int ans=(dis1[b]+dis1[c]+dis2[c])/2;//从a走到b加上从a走到c加上从b走到的总和除以2
cout<<ans<<endl<<a<<" "<<b<<" "<<c;
return 0;
}