Codeforces Round #635 (Div. 2) abcd

昨天晚上找的这套cf比之前那几套简单一些
到一点出了三题 感动 之前到一点b题才勉勉强强a掉

A. Ichihime and Triangle

题目思路

题目给出的三个区间都首尾相连
第二个区间右结点和第三个区间的左节点相同
所以输出这个点 在输出第一个区间的随便一个点就行

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 5e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =1e17+10;
const int mod = 2333;
 
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        printf("%d %d %d\n",b,c,c);
    }
}

B. Kana and Dragon Quest game

题目思路
题目给出一个数n 两种修改方式和修改方式各自使用的最大次数
第一种修改方式是让n除以2 在加10
第二种就直接减10
问能不能将n变为小于等于0的数

分析题目条件其实不难看出
当n小于等于20的时候 第一种方式不会是他的值减小
在做第一种操作时要进行特判
我们先判断n是否能直接被第二种操作变成小于等于0的数
如果不能在对n做第一种操作 直到到达最大次数或者n小于等于20时退出
在判断n是否能直接被第二种操作变成小于等于0的数
具体操作看代码

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 5e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =1e17+10;
const int mod = 2333;
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int x,n,m;
        scanf("%d%d%d",&x,&n,&m);
        int flag=0;
        for(int i=1;i<=n;i++)
        {
            if(x>20)
            {
                x=x/2+10;
            }else
                break;
 
        }
        if(x<=m*10)
            flag=1;
        else
            flag=0;
        if(flag==1)
            printf("YES\n");
        else
            printf("NO\n");
    }
}

C. Linova and Kingdom

题目思路

根据题意不难想出其实工业城市都放在叶子节点是最佳的
但是当叶子节点放满之后的情况就需要再考虑了
但我们叶子节点放满时 将最近的结点变成工业城市
此时他对总共的值的影响不只是加上他到根节点的距离
还要减去他的子树结点个数
因为他本身由旅游业城市变成了工业城市
他的子树上每一个结点的快乐值都要减一
所以我们可以记录树上每个节点的深度和子树结点个数
将每个结点的深度与子树节点个数的差值进行排序
选前k大的数相加就是题目答案了

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 5e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =1e17+10;
const int mod = 2333;
 
struct node
{
    int to,next;
}e[maxn<<1];
int len,first[maxn],dep[maxn],siz[maxn],a[maxn];
 
void add(int u,int v)
{
    e[len].to=v;
    e[len].next=first[u];
    first[u]=len++;
}
 
void dfs(int x,int fa)
{
    dep[x]=dep[fa]+1;
    siz[x]=1;
    for(int i=first[x];i!=-1;i=e[i].next)
    {
        int id=e[i].to;
        if(fa==id)continue;
        dfs(id,x);
        siz[x]+=siz[id];
    }
}
 
int main()
{
    ms(first,-1);
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs(1,-1);
    for(int i=1;i<=n;i++)
    {
        a[i]=dep[i]-siz[i];
    }
    sort(a+1,a+1+n);
    ll sum=0;
    for(int i=n;i>=n-k+1;i--)
    {
        sum+=a[i];
    }
    printf("%lld\n",sum);
}

emmmm又多了两个专题 d题等我写几道最短路的题 再来补把

我来补d题了 又是被自己演的一天
找了一个多小时bug 发现样例一直有个值不对
找来找去感觉没有什么细节是有问题的
最后发现我的inf开小了。。。。。
艹(一种植物)

D. Xenia and Colorful Gems

题目思路

将三个数组分别排序
暴力遍历的话 因为数据范围是1e5 最后是1e15会超
所以要想办法降复杂度
想了好久也没啥
看了题解才晓得怎么做
首先将三个数组分别排序
因为我们要找的是最小值
所以让选出的三个值之间的差距最小就是我们要的
令第一个数组为a 第二个数组为b 第三个数组为c
我们可以先遍历a数组
用lower_bound找在b和c数组第一个大于等于a[i]
这里考虑的是b和c大于a[i]时 他们能产生的最小的差值
我们好要考虑b和c小于a[i]时 他们能产生的最小差值
在同样遍历b c数组
感觉有点讲不清楚 建议搭配代码理解

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =0x3f3f3f3f3f3f3f3f;
const int mod = 2333;

int na,nc,nb;
ll a[maxn],b[maxn],c[maxn];

ll cal(ll a,ll b,ll c)
{
    return (a-b)*(a-b)+(b-c)*(b-c)+(c-a)*(c-a);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&na,&nb,&nc);
        for(int i=0;i<na;i++)
            scanf("%lld",&a[i]);
        for(int i=0;i<nb;i++)
            scanf("%lld",&b[i]);
        for(int i=0;i<nc;i++)
            scanf("%lld",&c[i]);
        sort(a,a+na);
        sort(b,b+nb);
        sort(c,c+nc);
        ll ans=llinf;
        for(int i=0;i<na;i++)
        {
            int x=lower_bound(b,b+nb,a[i])-b;
            int y=lower_bound(c,c+nc,a[i])-c;
            if(x==nb)x--;
            if(y==nc)y--;
            ans=min(ans,cal(a[i],b[x],c[y]));
            if(x>0)
                ans=min(ans,cal(a[i],b[x-1],c[y]));
            if(y>0)
                ans=min(ans,cal(a[i],b[x],c[y-1]));
            if(x>0&&y>0)
                ans=min(ans,cal(a[i],b[x-1],c[y-1]));
        }
        for(int i=0;i<nb;i++)
        {
            int x=lower_bound(a,a+na,b[i])-a;
            int y=lower_bound(c,c+nc,b[i])-c;
            if(x==na)x--;
            if(y==nc)y--;
            ans=min(ans,cal(b[i],a[x],c[y]));
            if(x>0)
                ans=min(ans,cal(b[i],a[x-1],c[y]));
            if(y>0)
                ans=min(ans,cal(b[i],a[x],c[y-1]));
            if(x>0&&y>0)
                ans=min(ans,cal(b[i],a[x-1],c[y-1]));
        }
        for(int i=0;i<nc;i++)
        {
            int x=lower_bound(a,a+na,c[i])-a;
            int y=lower_bound(b,b+nb,c[i])-b;
            if(x==na)x--;
            if(y==nb)y--;
            ans=min(ans,cal(c[i],a[x],b[y]));
            if(x>0)
                ans=min(ans,cal(c[i],a[x-1],b[y]));
            if(y>0)
                ans=min(ans,cal(c[i],a[x],b[y-1]));
            if(x>0&&y>0)
                ans=min(ans,cal(c[i],a[x-1],b[y-1]));
        }
        printf("%lld\n",ans);
    }

}

猜你喜欢

转载自blog.csdn.net/daydreamer23333/article/details/107375616