Codeforces Round #615 (Div. 3)

Posted shatianming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #615 (Div. 3)相关的知识,希望对你有一定的参考价值。

补一发欠下的题解...

A.题意:

给你四个正整数a,b,c,n问你能不能找到3个正整数A,B,C,满足A+a=B+b=C+c,且A+B+C==n

通过对题目的推导,只要这个成立就ok n-2*c+a+b=3C

又因为可能出现负数,所以要再判断一下

技术图片
#include<bits/stdc++.h>
using namespace std;

long long t,n,a[4];

bool cmp(long long x,long long y){
    return x<y;
}

int main(){
    cin>>t;
    for(int cishu=1;cishu<=t;cishu++){
        cin>>a[0]>>a[1]>>a[2]>>n;
        sort(a,a+3);
        if((n+a[0]+a[1]-2*a[2])%3==0&&((n+a[0]+a[1]-2*a[2]))>=0){
            cout<<"YES"<<endl;
        }
        else cout<<"NO"<<endl;
    }
}
View Code

B,题意

在平面坐标上给你多个点,并且每次让你从源点出发,且只能向上或向右移动,问能否全部经过这些点

嘛,挺简单的,

想一下不能经过的情况,,,就是横坐标比你小但纵坐标比你大,或者反过来...

很显然,先按照横坐标排序,找一下有没有横坐标比你小,但纵坐标比你大的....(记录一下最大值就好了)

技术图片
#include<bits/stdc++.h>
using namespace std;
 
typedef pair<int,int> PII;
const int N = 1007;
int n;
PII p[N];
void work() {
    cin>>n;
    p[0] = make_pair(0,0);
    for(int i=1,x,y;i<=n;++i) {
        cin>>x>>y;
        p[i] = make_pair(x,y);
    }
    sort(p+1, p+1+n);
    bool flag = 0;
    for(int i=2;i<=n;++i)
        if(p[i-1].second > p[i].second) {
            flag = 1; break ;
        }
    if(flag) {
        puts("NO"); return ;
    } else puts("YES");
    for(int i=1;i<=n;++i) {
        int R = p[i].first - p[i-1].first;
        int U = p[i].second - p[i-1].second;
        for(int j=1;j<=R;++j) cout << "R";
        for(int j=1;j<=U;++j) cout << "U";
    }
    cout << endl;
}
int main()
{
    int T;
    cin>>T;
    for(int cishu=1;cishu<=T;cishu++){
        work();
    }
    return 0;
}
 
View Code

C,题意

问你一个数能不能被分解为3个不同的数的乘积

太水了

技术图片
#include<bits/stdc++.h>
using namespace std;
 
int t;
long long num;
 
 
int main(){
    cin>>t;
    for(int cishu=1;cishu<=t;cishu++){
        cin>>num;
        bool judge=false;
        for(long long i=2;i<sqrt(num);i++){
            if(num%i==0){
                long long p=num/i;
                for(long long j=i+1;j<sqrt(p);j++){
                    if(p%j==0){
                        cout<<"YES"<<endl;
                        cout<<i<<" "<<j<<" "<<p/j<<endl;
                        judge=true;
                        break;
                    }
                }
                break;
            }
        }
        if(judge==false){
            cout<<"NO"<<endl;
        }
    }
}
View Code

D.题意

题意好麻烦自己领会,说做法就好了

只要注意,每次可以给加进去的数(+/-)kx

就可以归纳成右Q个X%x

然后从0跑,跑到没有元素可以覆盖到自己就ok

E.题意(摘自http://www.bubuko.com/infodetail-3393113.html)

给你一个 n * m 的矩阵,你执行两种操作:

① 把矩阵中任意一个元素改为任意一个数

② 把矩阵中任意一列整体往上挪一个单元格,如右图矩阵我们对第一列向上挪了一个单元格技术图片

要求用最少的操作次数使矩阵 a[i][j] = (i - 1) * m + j

嘛,很显然;啦,当然是竖着来搞

那么很ok,我们现在的问题转换为对于一串序列,找到一段与1 2 3 4 5...最相似的一段序列

暴力的话要O(NNM)

讲道理我想KMP 

打扰了

技术图片
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
 
const int N = 2e5+7;
int n,m,ans;
int cnt[N];
vector<int> seq[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) {
            int x;
            cin>>x;
            x--;
            if(x%m+1 == j) seq[j].push_back(x/m);
            else seq[j].push_back(INF);
        }
    for(int i=1;i<=m;++i) {
        for(int i=0;i<n;++i) cnt[i] = 0;
        int res = INF;
        for(int j=0;j<seq[i].size();++j) {
            if(seq[i][j] >= n) continue;
            cnt[(j-seq[i][j]+n)%n]++;
        }
    
        for(int i=0;i<n;++i)
            res = min(res,n-cnt[i]+i);
        ans += res;
    }
    cout<<ans<<endl;
    return 0;
}
View Code

F,

 嘛,题目要求的是求三个点,使得他们组成的路径上第一次出现过的边的数量最大

直接求树的直接,然后求离树的直径最远的节点...就好了

乱搞就ok了,没思维

技术图片
#include<bits/stdc++.h>
using namespace std;

int n,tot=(-1),h[200005],last[200005],dis[200005],maxl=1,sum=0,id[200005],a1=(-1),a2=(-1),a3;
bool judge[200005],vis[200005];
struct node{
    int from,to,next;
}e[600005];

void add(int x,int y){
    tot++;
    e[tot].from=x;
    e[tot].to=y;
    e[tot].next=h[x];
    h[x]=tot;
}

int dfs(int now,int fa){//找离自己最远的节点 
    for(int i=h[now];i!=(-1);i=e[i].next){
        if(e[i].to!=fa&&judge[e[i].to]==false){
            dis[e[i].to]=dis[now]+1;
            last[e[i].to]=now;
            if(dis[e[i].to]>dis[maxl])maxl=e[i].to;
            dfs(e[i].to,now);
        }
    }
}


int main(){
    memset(judge,false,sizeof(judge));
    memset(h,-1,sizeof(h));
    bool ok=false;
    cin>>n;
    for(int i=1;i<n;i++){
    int x,y;cin>>x>>y;
    add(x,y);
    add(y,x);
    id[x]++;id[y]++;
    if(id[x]>2||id[y]>2)ok=true;
    }
    if(ok==false){
        for(int i=1;i<=n;i++){
            if(id[i]==1&&a1==(-1))a1=i;
            else if(id[i]==1&&a2==(-1))a2=i;
            else if(id[i]!=1){a3=i;}
        }
        cout<<n-1<<endl;
        cout<<a1<<" "<<a2<<" "<<a3<<endl;
        exit(0);
    }
    int a,b,c;
    dis[1]=0;
    dfs(1,-1);a=maxl;
    memset(dis,0,sizeof(dis));
    dis[maxl]=0;dfs(maxl,-1);b=maxl;sum+=dis[b];
    memset(dis,0,sizeof(dis));maxl=a;
    for(int now=b;now!=a;now=last[now])judge[now]=true;
    judge[a]=true;
    maxl=a;
    for(int now=b;now!=a;now=last[now])dfs(now,-1);
    dfs(a,-1);
    sum+=dis[maxl];
    cout<<sum<<endl;
    cout<<a<<" "<<b<<" "<<maxl<<endl;
}
View Code

 

总体来说还是挺简单的吧,div2随便一道E就比这些难(连题目都看不懂好吧)

贼高兴,我变蓝了,但我还是改不了我的qq名字,因为是不ak csp不改名......

技术图片

 

嘛,新的一年,难以得当把(不要把我搞得太蓝(难)了) 

以上是关于Codeforces Round #615 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #615(Div.3)解题报告

Codeforces Round #615 (Div. 3)

Codeforces Round #615 (Div. 3)

Codeforces Round #615 (Div. 3)

Codeforces Round #615 (Div. 3)

Codeforces Round #615 (Div. 3)