Codeforces Round #615(Div. 3)全部题解

eg:Round 615我是开小号打的,一场上蓝真滴很高兴QvQ,E题着实脑子抽了没来得及写完,贪心写的很fake。赛后第二天补了E,然后今天才补了F。那开始补档。在这里插入图片描述

A. Collecting Coins

题意:T组数据,每组给出四个整数A,B,C,N。问是否可以合理分配N使得A+a=B+b=C+c且a+b+c=N。
题解:将三个整数从小到大排序,假设排完的顺序为A,B,C。先看N是否大于等于C-A+C-B,再看N是否是3的倍数就好了。

#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
#include "map"
#include "set"
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f;
const int mod=1e9+7;
int f[5];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int a,b,c,n;  
        scanf("%d%d%d%d",&f[1],&f[2],&f[3],&n);
        sort(f+1,f+1+3);
        int ans=f[3]-f[1]+f[3]-f[2];
        if(ans>n)puts("NO");
        else{
            ans=n-ans;
            if(ans%3==0)puts("YES");
            else puts("NO");
        }
    }
    return 0;
}

B. Collecting Packages

题意:T组数据,每组有n个点。出发点在(0,0),每次只能向上或者向右走,问是否可以完全走完这n个点,如果可以走完按照字典序最小输出。
题解:sort排序题,显然R<U,所以我们先排横座标再排纵座标,然后扫描一遍即可。

#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
#include "map"
#include "set"
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f;
const int mod=1e9+7;
int n;
struct arr{
    int x,y;
}f[1010];
int m[1010][1010];
bool cmp(arr a,arr b){
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
string s;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        s.clear();
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&f[i].x,&f[i].y);
        sort(f+1,f+1+n,cmp);
        int nowx=0,nowy=0,flag=0,cnt=0;
        for(int i=1;i<=n;i++){
            if(f[i].x>=nowx && f[i].y>=nowy){
                for(int j=0;j<f[i].x-nowx;j++)s=s+"R";
                for(int j=0;j<f[i].y-nowy;j++)s=s+"U";
                nowx=f[i].x;nowy=f[i].y;
            }else {
                flag=1;
                break;
            }
        }
        if(flag)puts("NO");
        else{
            puts("YES");
            cout<<s<<endl;
        }
    }
    return 0;
}

C. Product of Three Numbers

题意:t组数据,给出一个十进制正整数n,问可否找出三个整数a,b,c使得2a<b<c2\leqslant a<b<c,且abc=na*b*c=n
题解:直接对n的所有因数进行暴力枚举,再对其中一个因数进行暴力枚举,检查三个数是否相等即可。

#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
#include "map"
#include "set"
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f;
const int mod=1e9+7;
int n;
int f[4];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int flag=0;
        for(int i=2;i*i<=n;i++)
            if(n%i==0){
                for(int j=2;j*j<=n/i;j++)
                    if(j!=i && (n/i)%j==0){
                        if(n/i/j!=i && n/i/j!=j){
                            f[0]=i,f[1]=j,f[2]=n/i/j;
                            flag=1;
                            break;
                        }
                        if(flag)break;
                    }
                if(flag)break;
            }
        if(!flag)puts("NO");
        else {
            sort(f,f+3);
            puts("YES");
            printf("%d %d %d\n",f[0],f[1],f[2]);
        }
    }
    return 0;
}

D. MEX maximizing

题意:给出q个整数和一个整数x,每次读入一个整数n,可以将n变成ndxn-d*x或者n+dxn+d*x,其中d为任意正整数,此外进行MEX操作,输出最大的MEX值。(MEX:输出最小的不在集合里的非负整数)
题解:每次读入一个数字,都取模x,按照最小的往上累加即可。用map记录一下,答案每次往上check即可。

#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
#include "map"
#include "set"
using namespace std;
const int maxn=4e5+10;
const int INF=0x3f3f3f;
const int mod=1e9+7;
int n,q,x;
map<int,int>mmap;
int f[maxn];
int main(){
    scanf("%d%d",&q,&x);
    int ans=0;
    while(q--){
        int s;
        scanf("%d",&s);
        s%=x;
        if(mmap[s]==1)mmap[f[s]+x]=1,f[s]+=x;
        else mmap[s]=1,f[s]=s;
        while(mmap[ans]==1)ans++;
        //for(int i=0;i<10;i++)printf("%d ",mmap[i]);
        printf("%d\n",ans);
    }
    return 0;
}

E. Obtain a Permutation

题意:给出一个nm的矩阵,每次可以从两个操作里面选择一个(1:任意替换a[i][j]为1~nm的数中的任意一个,2:任意转动第i列),问将矩阵排列成1 2 3 …… n*m的矩阵要最少多少次。
题解:对每一列考虑贪心。f[i]表示向上移动i次则可以将该列达到最终状态且需要改变f[i]个该列的元素。将f数组全置为n,判断该元素是否属于该列,如果属于,则判断对应向上移动几次,假设移动p次,则f[p]1f[p]-1,之后只要扫描一遍数组选个最小的即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
vector<int>G[maxn]; 
int f[maxn];
int n,m;
ll ans;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)G[i].push_back(0);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			int x;
			scanf("%d",&x);
			G[i].push_back(x);
		}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++)f[j]=n;
		for(int j=1;j<=n;j++)
			if((G[j][i]-i)%m==0){
				int k=(G[j][i]-i)/m+1;
				if(k>n)continue;
				if(j<k)j+=n;
				f[j-k+1]--;
				if(j>n)j-=n;
			}
		int sum=INF;
		for(int j=1;j<=n;j++)sum=min(sum,f[j]+j-1);
		ans+=1ll*sum;
	}
	printf("%lld\n",ans);
	return 0;
}

F. Three Paths on a Tree

题意:任给一颗树,找出树上三个点a,b,c使得这三个点之间的简单路径最长。
题解:贪心的思想,找出树的直径,就可以确定a点和b点了。之后枚举其余的点到a和b距离找到一个最长的即可。

#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
#include "map"
#include "set"
#include "queue"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int INF=0x3f3f3f;
const int mod=1e9+7;
vector<int>G[maxn];
queue<int>q;
int n,a,b,c,pos,st,sum;
int vis[maxn],dis[maxn],dis1[maxn],dis2[maxn];
int ans1,ans2,ans3;
void bfs(int x){
    q.push(x);
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    vis[x]=1;
    int u=x,cnt=0;
    while(!q.empty()){
        int v=q.front();
        q.pop();
        for(int i=0;i<G[v].size();i++)
            if(!vis[G[v][i]]){
                vis[G[v][i]]=1;
                q.push(G[v][i]);
                dis[G[v][i]]=dis[v]+1;
                if(dis[G[v][i]]>cnt)u=G[v][i],cnt=dis[G[v][i]];
            }
    }
    pos=u;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);st=x;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    bfs(st);a=pos;//find a
    bfs(a);b=pos;//find b
    for(int i=1;i<=n;i++){//other to a_dis
        dis1[i]=dis[i];
        if(dis1[i]>sum){
            b=i;sum=dis1[i];ans1=dis1[i];
        }
    }
    bfs(b);sum=0;
    for(int i=1;i<=n;i++){//other to b_dis
        dis2[i]=dis[i];
        if(dis1[i]>sum)sum=dis2[i];
    }
    for(int i=1;i<=n;i++)//find c
        if(dis1[i]+dis2[i]>ans2+ans3 && i!=a && i!=b){
            c=i;
            ans2=dis1[i],ans3=dis2[i];
        }
    printf("%d\n",(ans1+ans2+ans3)/2);
    printf("%d %d %d\n",a,b,c);
    return 0;
}

发布了8 篇原创文章 · 获赞 8 · 访问量 1579
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章