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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章