zoukankan      html  css  js  c++  java
  • Codeforces Round #203 (Div. 2) 题解

    A.TL

    题意:有n(100)个数的序列a,以及m(100)个序列b,问max(mina*2,maxa)是否小于minb

    思路:直接查找即可

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    int a[105],b[105];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)scanf("%d",&b[i]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+m);
        int ans=max(a[1]*2,a[n]);
        if(ans>=b[1])puts("-1");
        else printf("%d
    ",ans);
        return 0;
    }
    View Code

    B.Resort

    题意:给你一张n(1e5)个点的图,点有两种类型,一种是起点,一种是终点,问你从任意起点开始,打印到达终点的最长路,路径满足除终点外其他的点都是起点,从起点到终点不能有岔路,路径是唯一的,路径上的点出度为1

    思路:反向建图,然后从每个终点开始搜索,维护最长路径的起点和终点,最后在搜索出路径,打印即可

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=1e5+7;
    int n;
    vector<int>mp[maxn];
    bool vis[maxn];
    int anss,anst,ansl;
    int in[maxn];
    int stk[maxn],top;
    void dfs(int s,int x,int num)
    {
        for(int i=0;i<mp[x].size();i++){
            int v=mp[x][i];
            if(vis[v])continue;
            if(in[v]<=1){
                if(num+1>ansl){
                    anss=s;anst=v;ansl=num+1;
                }
                dfs(s,v,num+1);
            }
        }
    }
    void dfs(int x,int t)
    {
        stk[++top]=x;
        if(x==t)return ;
        for(int i=0;i<mp[x].size();i++){
            dfs(mp[x][i],t);
        }
    }
    int main()
    {
        top=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&vis[i]);
            if(vis[i])anss=i,anst=i,ansl=1;
        }
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            if(!x)continue;
            mp[i].push_back(x);
            in[x]++;
        }
        for(int i=1;i<=n;i++){
            if(!vis[i])continue;
            dfs(i,i,1);
        }
        dfs(anss,anst);
        printf("%d
    ",top);
        for(int i=top;i>=1;i--){
            printf("%d ",stk[i]);
        }
        puts("");
        return 0;
    }
    View Code

    C.Bombs

    题意:平面上有n(1e5)个炸弹,有一个机器人在(0,0)点,机器人有3中操作

    1 x dir 表示机器人向dir(UDLR)方向走了x格,

    2 表示机器人捡起炸弹

    3 表示机器人摧毁炸弹

    机器人智能在(0.0)处摧毁炸弹,问你机器人最少需要多少步可以清除所有的炸弹,机器人身上只能带一个炸弹,没有炸弹在两个相同的点,以及炸弹不会再(0,0)点

    思路:对炸弹到原点的距离进行排序,然后直接打印指令。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=1e5+7;
    struct point
    {
        int x,y;
        bool operator <(const point &b)const
        {
            return abs(x)+abs(y)<abs(b.x)+abs(b.y);
        }
    }a[maxn];
    int n;
    int main()
    {
        scanf("%d",&n);
        int ans=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            if(a[i].x!=0)ans++;
            if(a[i].y!=0)ans++;
        }
        sort(a+1,a+1+n);
        ans*=2;ans+=n*2;
        printf("%d
    ",ans);
        for(int i=1;i<=n;i++){
            if(a[i].y > 0) printf("1 %d U
    ", abs(a[i].y));
            if(a[i].y < 0) printf("1 %d D
    ", abs(a[i].y));
            if(a[i].x > 0) printf("1 %d R
    ", abs(a[i].x));
            if(a[i].x < 0) printf("1 %d L
    ", abs(a[i].x));
            printf("2
    ");
            if(a[i].y > 0) printf("1 %d D
    ", abs(a[i].y));
            if(a[i].y < 0) printf("1 %d U
    ", abs(a[i].y));
            if(a[i].x > 0) printf("1 %d L
    ", abs(a[i].x));
            if(a[i].x < 0) printf("1 %d R
    ", abs(a[i].x));
            printf("3
    ");
        }
        return 0;
    }
    View Code

    D.Looking for Owls

    题意:平面上有3e5条线段,以及1000个圆,满足下面四个条件就称做猫头鹰,问平面上有多少个猫头鹰

    1. 圆ij相对于线段k对称
    2. 圆ij不想交
    3. 圆ij有相同的半径
    4. 线段k和圆ij圆心连线相交

    思路:因为圆的范围小,所以n2枚举圆,然后判断线段,把每条线段都按照斜率和截距进行标记,相同的存在一个vector中,对于同一个vector中的线段在按照差分的方法标记有多少线段覆盖了圆ij圆心的中点,最后统计答案即可

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef pair<int,pair<int,int> >piii;
    struct point
    {
        int x,y;
        void input()
        {
            scanf("%d%d",&x,&y);
        }
        point(int x=0,int y=0):x(x),y(y){}
        int len()
        {
            return x*x+y*y;
        }
        point operator +(const point &b)const
        {
            return point(x+b.x,y+b.y);
        }
        point operator *(const int v)const
        {
            return point(v*x,v*y);
        }
        point operator -(const point &b)const
        {
            return point(x-b.x,y-b.y);
        }
        point operator /(const int v)const
        {
            return point(x/v,y/v);
        }
    };
    
    #define sqr(x) ((x)*(x))
    int dis(point a,point b)
    {
        return (a-b).len();
    }
    
    piii getpiii(point a,point b)
    {
        int dx=a.x-b.x,dy=a.y-b.y;
        if(dy==0)return make_pair(a.y,make_pair(0,0));
        if(dx==0)return make_pair(a.x,make_pair(0,1));
        if(dx<0){
            dx*=-1,dy*=-1;
        }
        int d=__gcd(abs(dx),abs(dy));
        dx/=d;dy/=d;
        int res=(a.y%dy+dy)%dy;
        res=a.x+(res-a.y)/dy*dx;
        return make_pair(res,make_pair(dx,dy));
    }
    piii mipiii(point a,point b)
    {
        point mid=(a+b)/2,ve=a-b;
        swap(ve.x,ve.y);ve.x*=-1;
        return getpiii(mid+ve,mid-ve);
    }
    map<piii,vector<pair<int,int> > > mp;
    map<piii,vector<int> >ans;
    
    int getans(piii s,int v)
    {
        if(mp.find(s)==mp.end())return 0;
        vector<pair<int,int> >&use=mp[s];
        int pos=upper_bound(use.begin(),use.end(),make_pair(v,1))-use.begin();
        return ans[s][pos];
    }
    
    const int maxn=2500;
    point cir[maxn];
    int r[maxn];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        point a,b;
        for(int i=1;i<=n;i++){
            a.input();b.input();
            a=a*2;b=b*2;
            if(a.x != b.x){
                mp[getpiii(a,b)].push_back(make_pair(min(a.x,b.x),1));
                mp[getpiii(a,b)].push_back(make_pair(max(a.x,b.x)+1,-1));
            }
            else{
                mp[getpiii(a,b)].push_back(make_pair(min(a.y,b.y),1));
                mp[getpiii(a,b)].push_back(make_pair(max(a.y,b.y)+1,-1));
            }
        }
        for(auto &it:mp){
            sort(it.second.begin(),it.second.end());
            vector<int> &res=ans[it.first];
            int pre=0;
            res.push_back(pre);
            for(auto j:it.second){
                pre+=j.second;
                res.push_back(pre);
            }
        }
        for(int i=0;i<m;i++){
            cir[i].input();
            scanf("%d",&r[i]);
            cir[i]=cir[i]*2;
            r[i]*=2;
        }
        int res=0;
        for(int i=0;i<m;i++){
            for(int j=i+1;j<m;j++){
                if(r[i]==r[j]&&dis(cir[i],cir[j])>sqr(r[i]+r[j])){
                    int mid;
                    if(cir[i].y==cir[j].y)mid=cir[i].y;
                    else mid=(cir[i].x+cir[j].x)/2;
                    res+=getans(mipiii(cir[i],cir[j]),mid);
                }
            }
        }
        printf("%d
    ",res);
        return 0;
    }
    View Code

    E.Wrong Floyd

    题意:给你n个点和m条边,以及一个点集k,构造出下面代码答案错误的一张图

    思路:因为有的点没有遍历到,所以肯定有的地方没有达到最小值,找到一个没有在点集中的点,如果找不到肯定是全部覆盖到了,找到这个点后,在点集k中随便选一个点,把点集中的点记为s,点集外的点记为e,先把se中间连一条边,然后把其他的点尽可能的建边达到完全图,但不和e点,此时的建图都是可是让代码产生错误的,点e没有被松弛到,如果还有余边就把不等于se并且不再点集k中的点建边,这些边依然不会贡献答案如果还有边,那么代表最后的答案肯定都会被松弛,打印-1,如果没有剩余的边,就直接打印构造即可

    代码:

     

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=305;
    bool vis[maxn];
    vector<pair<int,int> >ans;
    
    int n,m,k;
    
    bool check()
    {
        int s=0,e=0;
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                s=i;break;
            }
        }
        if(s==0)return false;
        for(int i=1;i<=n;i++){
            if(vis[i]){
                e=i;break;
            }
        }
        ans.push_back(make_pair(s,e));
        m--;
        for(int i=1;i<=n;i++){
            if(i==e)continue;
            for(int j=i+1;j<=n;j++){
                if(j==e)continue;
                if(m>0)ans.push_back(make_pair(i,j)),m--;
            }
        }
        for(int i=1;i<=n;i++){
            if(i==s||i==e)continue;
            if(m>0&&!vis[i])ans.push_back(make_pair(i,e)),m--;
        }
        return m==0;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++){
            int x;
            scanf("%d",&x);
            vis[x]=true;
        }
        if(!check()){
            puts("-1");
        }
        else{
            for(int i=0;i<ans.size();i++){
                printf("%d %d
    ",ans[i].first,ans[i].second);
            }
        }
        return 0;
    }
    View Code

     

     

  • 相关阅读:
    2018年蓝桥杯java b组第五题
    2018年蓝桥杯java b组第四题
    2018年蓝桥杯java b组第三题
    2018年蓝桥杯java b组第二题
    2018年蓝桥杯ava b组第一题
    java算法基础范例
    2015年蓝桥杯java b组第十题
    第六届蓝桥杯java b组第8题
    MySQL之数据表(五)
    MySQL数据类型(四)
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/10391855.html
Copyright © 2011-2022 走看看