Codeforces Round #615(div.3)

Codeforces Round #615 div.3

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值