zoukankan      html  css  js  c++  java
  • Codeforces Round #615 (Div. 3)

    QAQ

    A. Collecting Coins

    题意:

    有三堆硬币,数目分别是abc,现在你手上还有n枚硬币,问能否通过合理分配n枚硬币到这三堆硬币里,使得这三堆硬币数目相同。

    思路:

    求所有硬币的和sumcheck一下sum是否是三的倍数且每一堆硬币的数目都小于等于sum/3

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int main()
    {
       int t;
       ll a,b,c,n;
       cin >> t;
       while(t--)
       {
           cin >> a >> b >> c >> n;
           ll sum = a+b+c+n;
           if(sum%3!=0)
           {
                printf("NO
    ");continue;
           }
    
    
           sum/=3;
           if(a>sum||b>sum||c>sum)
            printf("NO
    ");
           else
            printf("YES
    ");
       }
        return  0;
    }

    B. Collecting Packages

    题意:

    在一个二维平面上有n个点,一个机器人从原点出发,只能往上或往右走,问机器人能否经过所有的点,如果可以输出最短路径。

    思路:

    可以将横坐标作为第一关键字,纵坐标作为第二关键字对所有点进行排序,然后暴力模拟即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    struct Point
    {
        int x,y;
        Point(int _x=0,int _y =0):x(_x),y(_y){}
        bool operator <(const Point&b)
        {
            if(x==b.x)
                return y<b.y;
            return x<b.x;
        }
    };
    vector<Point>vec;
    string ans;
    bool solve(int n)
    {
        int x = 0,y = 0;
        for(int i =0;i<n;i++)
        {
            int x1 = vec[i].x,y1 =vec[i].y;
            if(x1<x)
                return false;
            if(y1<y)
                return false;
            for(x;x<x1;x++)
                ans+='R';
            for(y;y<y1;++y)
                ans+='U';
        }
        return true;
    }
    int main()
    {
       int t;
       cin >> t;
       while(t--)
       {
           ans = "";
           vec.clear();
           int n;
           cin >>n;
           int x,y;
           for(int i = 0;i<n;++i)
           {
                cin >>x >>y;
                vec.push_back(Point(x,y));
           }
           sort(vec.begin(),vec.end());
          if(solve(n))
          {
              printf("YES
    ");
              cout << ans << "
    ";
          }
          else
            printf("NO
    ");
    
       }
        return  0;
    }

    C .Product of Three Numbers

    题意:

    输入一个数n,问能不能拆分成三个大于2且完全不同的数abc,且a*b*c = n;

    思路:

    可以对n进行素数拆分,然后分类讨论即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    struct Prime
    {
        int x,n;
        Prime() {}
        Prime(int _x,int _n):x(_x),n(_n) {}
    
    };
    vector<Prime>vec;
    ll qp(ll x,ll n)
    {
        ll res = 1;
        while(n>0)
        {
            if(n&1)res = res*x;
            x = x*x;
            n>>=1;
        }
        return res;
    }
    void solve(ll n)
    {
        ll tmp = n;
        for(int i = 2; i*i<=n; ++i)
        {
            int cnt = 0;
            while(n%i==0)
            {
                cnt++;
                n/=i;
            }
            if(cnt>0)
                vec.push_back(Prime(i,cnt));
        }
        if(n!=1)
            vec.push_back(Prime(n,1));
    //    int len = vec.size();
    //    cout << len << endl;
    //    for(int i =  0;i<len;++i)
    //    {
    //        cout << vec[i].x<< " " << vec[i].n << "
    ";
    //    }
        ll a=1,b=1,c=1;
        if(vec.size()>=3)
        {
            printf("YES
    ");
            a = qp(vec[0].x,vec[0].n);
            b = qp(vec[1].x,vec[1].n);
            c = tmp/(a*b);
            cout << a << " " <<b << " " << c << "
    ";
            return ;
        }
        if(vec.size()==2)
        {
            if(vec[0].n<2&&vec[1].n<2)
            {
                printf("NO
    ");
                return ;
            }
            if(vec[0].n<vec[1].n)
                swap(vec[0],vec[1]);
           a = vec[0].x;
           b = vec[1].x;
           c = tmp/(a*b);
           if(c!=a&&c!=b)
           {
               printf("YES
    ");
                cout << a << " " <<b << " " << c << "
    ";
                return ;
           }
           else
            printf("NO
    ");
           return ;
    
    
        }
        if(vec.size()==1)
        {
            if(vec[0].n<6)
            {
                printf("NO
    ");
                return ;
            }
            a = vec[0].x;
            b = vec[0].x*vec[0].x;
            c = tmp/(a*b);
            printf("YES
    ");
            cout << a << " " <<b << " " << c << "
    ";
            return ;
        }
        printf("NO
    ");
        return;
    }
    int main()
    {
        //freopen("out.txt","w",stdout);
        int t;
        cin >> t;
        while(t--)
        {
            vec.clear();
            ll n;
            cin >> n;
            solve(n);
        }
    
        return  0;
    }

    D. MEX maximizing

    题意:

    定义一个数组的MEX为数组中第一个未出现的数,开始给你一个空数组以及一个数x,并伴有q次查询,每次查询输入一个数,你可以把这个数加上x无数次或者减x无数次,然后将它插入到数组中,使得每次插入后所得MEX最大。

    思路:

    首先,(ans-x)%x = ans%x = (ans+x)%x,因此我们就可以用一个数组cnt去模拟上面的数组了,首先对于每一次查询,它的答案不可能比上次查询要小,对于每次输入进来的那个数a,我们可以cnt[a%x]++,这个思路是把原先的一维数轴根据x分为若干段,对于a来说,无论它如何变化,它在某一段中的相对位置不会改变,这个位置也就是a%x,因此,我们可以开始从上一次查询的结果开始,不断循环,查询到底是那一段的那个位置缺失,这个数就是答案。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 4e5+10;
    int num[maxn];
    int main()
    {
        int q,x,a;
        scanf("%d %d",&q,&x);
        int ans = 0;
        while(q--)
        {
            scanf("%d",&a);
            num[a%x]++;
            while(1)
            {
                if(num[ans%x]==0)
                    break;
                num[ans%x]--;
                ++ans;
            }
            cout << ans << "
    ";
        }
        return 0;
    }

    E. Obtain a Permutation

    题意:

    给你一个n*m的矩阵,定义一个move,在一个move你可以进行两种操作,一是选择矩阵中的任何一个元素将他替换成另一个值,二是选择任意一列将他的所有元素循环向上移动一位,问将该矩阵变成

     

    所需要的最小move数。

    思路:

    首先,通过题意我们可以知道,每一列都是独立的,即对这一列的操作是不会影响到其他列的。因此,我们可以一列一列分开计算。对于某一列的某个元素,我们根据它的位置就可以知道这个位置的值应该是什么,我们枚举这一列的所有元素,假如这个元素是属于这一列的元素,我们可以计算出使它到它应该去的位置所需要的操作数,接下来,枚举操作数,不能移动得到的元素就只能更改了,对于每一个操作数,更新答案即可。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 4e5+10;
    int num[maxn];
    int main()
    {
        int q,x,a;
        scanf("%d %d",&q,&x);
        int ans = 0;
        while(q--)
        {
            scanf("%d",&a);
            num[a%x]++;
            while(1)
            {
                if(num[ans%x]==0)
                    break;
                num[ans%x]--;
                ++ans;
            }
            cout << ans << "
    ";
        }
        return 0;
    }

    F. Three Paths on a Tree

    题意:

    给你一颗有n个结点的树,让你求树上三点a,b,c,使ab,bcca,这三条路径所经历的不重复的边数最多。

    思路:

    首先,这三个点一定有两个端点是在树的直径上,这里通过两次bfs求树的直径,然后枚举c点,因为每个点到两个端点的距离已经通过两次bfs得到,但要注意c不能与a,b点相同。

    得到结果除2就是最终答案。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn =2e5+10;
    vector<int> a[maxn];
    int n,vis[maxn],dis1[maxn],dis2[maxn],dis[maxn],pos;
    void bfs(int x)
    {
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        pos = x;
        vis[x] = 1,dis[x] = 0;
        queue<int>q;
        q.push(x);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i = 0;i<a[u].size();++i)
            {
                if(!vis[a[u][i]])
                {
                    vis[a[u][i]] = 1;
                    dis[a[u][i]] = dis[u]+1;
                    q.push(a[u][i]);
                    if(dis[a[u][i]]>dis[pos]) pos=a[u][i];
                }
            }
        }
    }
    int  main()
    {
        scanf("%d",&n);
        int u,v;
        for(int i = 1;i<n;++i)
        {
            scanf("%d %d",&u,&v);
            a[u].push_back(v);
            a[v].push_back(u);
        }
        int a,b,c;
        bfs(1);a = pos;
        
        bfs(pos);b= pos;
        for(int i = 1;i<=n;++i)
            dis1[i] = dis[i];
        bfs(pos);
        for(int i = 1;i<=n;++i)
            dis2[i] = dis[i];
        c = 0;
        for(int i =1;i<=n;++i)
        {
            if(dis1[i]+dis2[i]>dis1[c]+dis2[c]&&i!=a&&i!=b) c =i;
        }
        int ans = (dis1[b]+dis2[c]+dis1[c])/2;
        cout << ans <<endl;
        cout  << a << " "<< b << " " <<c;
    
        return 0;
    }
  • 相关阅读:
    jQuery 小特效【文本框折叠隐藏,展开显示】【下拉菜单】【颜色渐变】【弹窗+遮罩】
    jQuery 【事件】【dom 操作】
    jQuery 【选择器】【动画】
    LINQ 小项目【组合查询、分页】
    LINQ 【高级查询】
    LINQ 【增、删、改、查】数据绑定
    WebFrom 【文件上传】
    【转】c# 字符串大小写混合转换
    【转】C#之继承
    类库,通用变量,is/as运算符,委托。
  • 原文地址:https://www.cnblogs.com/baihualiaoluan/p/12286482.html
Copyright © 2011-2022 走看看