zoukankan      html  css  js  c++  java
  • Codeforces Round #615 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1294

    A.

    给出a、b、c三个数,从n中分配给a、b、c,问能否使得a = b = c。计算a,b,c三个数的差值之和,n对其取余,判断是否为0即可。

    AC代码:

     1     #include<iostream>
     2     #include<vector>
     3     #include<algorithm>
     4     #include<cmath>
     5     #include<cstring>
     6     #include<queue>
     7     #include<cstdio>
     8     #include<stack>
     9     #include<unordered_map>
    10     #define inf 0x3f3f3f3f
    11     using namespace std;
    12     typedef long long ll;
    13     int main(){
    14         int t;
    15         scanf("%d",&t);
    16         while(t--){
    17             int n,a,b,c;
    18             scanf("%d%d%d%d",&a,&b,&c,&n);
    19             if(a<b) swap(a,b);
    20             if(a<c) swap(a,c);
    21             if(b<c) swap(b,c);
    22             int dif = a - b + a - c;
    23             if((n - dif)%3 == 0 && (n - dif)>=0) printf("YES
    ");
    24             else printf("NO
    ");
    25             
    26         }
    27         return 0;
    28     }

    B. Collecting Packages

    题意:给定一些点的坐标,问从起点开始移动,能否经过所有的点,且每次只能向上向右移动,求出路径。

    思路:所有点按横纵坐标排序,扫一遍所有的点,每次先向右再向上走。

     1  
     2     #include<iostream>
     3     #include<vector>
     4     #include<algorithm>
     5     #include<cmath>
     6     #include<cstring>
     7     #include<queue>
     8     #include<cstdio>
     9     #include<stack>
    10     #include<unordered_map>
    11     #define inf 0x3f3f3f3f
    12     using namespace std;
    13     typedef long long ll;
    14     const int maxn = 1005;
    15     struct node{
    16         int x,y;
    17     };
    18     bool cmp(node a,node b){
    19         if(a.x == b.x ) return a.y < b.y ;
    20         return a.x < b.x ;
    21     }
    22     int main(){
    23         int t;
    24         scanf("%d",&t);
    25         while(t--){
    26             int n;
    27             scanf("%d",&n);
    28             node g[maxn];
    29             for(int i = 1;i<=n;i++) {
    30                 scanf("%d%d",&g[i].x,&g[i].y);
    31             }
    32             sort(g+1,g+1+n,cmp);
    33             string ans = "";
    34             int f = 1;
    35             int curx = 0,cury = 0;
    36             for(int i = 1;i<=n;i++){
    37                 if(i == 1){
    38                     int lenR = g[i].x - curx;
    39                     int lenU = g[i].y - cury;
    40                     ans.append(lenR,'R'); 
    41                     ans.append(lenU,'U'); 
    42                     curx = g[i].x ,cury = g[i].y ;
    43                 }
    44                 else{
    45                     if(g[i].x < curx || g[i].y < cury){
    46                         cout<<"NO"<<endl;
    47                         f = 0;
    48                         break;
    49                     }
    50                     int lenR = g[i].x - curx;
    51                     int lenU = g[i].y - cury;
    52                     ans.append(lenR,'R'); 
    53                     ans.append(lenU,'U');     
    54                     curx = g[i].x ,cury = g[i].y ;
    55                 }
    56             }
    57             if(f == 0) continue;
    58             cout<<"YES"<<endl;
    59             cout<<ans<<endl;
    60         }
    61         return 0;
    62     }

    C. Product of Three Numbers

    题意:求不同的三个数a、b、c,使得a*b*c = n

    思路:自己的做法有点复杂,用唯一分解定理做,枚举n的质因子,用质因子去组合成a,b,c,最后判断。

     1 #include<iostream>
     2 #include<vector>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<queue>
     7 #include<cstdio>
     8 #include<map>
     9 #include<set>
    10 #include<stack>
    11 #include<unordered_map>
    12 #define inf 0x3f3f3f3f
    13 using namespace std;
    14 typedef long long ll;
    15 void solve(){
    16     int n;
    17     cin>>n;
    18     int tn = n;
    19     set<int> s;
    20     int a,b;
    21     int t = 1;
    22     for(int i = 2;i*i<=n;i++){
    23         while(n%i == 0){//枚举质因子
    24             n/=i;
    25             t = t*i;
    26             if(s.count(i) == 0 ){
    27                 s.insert(i);
    28                 t = 1;
    29             }
    30             if(s.count(t) == 0 && t!=1){
    31                 s.insert(t);
    32                 t = 1;
    33             }
    34             if(s.size() == 2){
    35                 set<int>::iterator iter = s.begin();
    36                 int x=*iter;
    37                 iter++;
    38                 x*=*iter;
    39                 if(s.count(tn/x) == 0 && tn/x!=1) {
    40                     s.insert(tn/x);
    41                     break;
    42                 }
    43             
    44             }
    45             if(s.size()>=3) {
    46                 break;
    47             }
    48         }
    49         if(s.size()>=3) break;
    50     }
    51     if(s.size()>=3){
    52         cout<<"YES"<<endl;
    53         set<int>::iterator iter = s.begin();
    54         while(iter!=s.end()){
    55             cout<<*iter<<" ";
    56             iter++;
    57         }
    58     }
    59     else{
    60         cout<<"NO"<<endl;
    61     }
    62 }
    63 int main(){
    64     int t;
    65     cin>>t;
    66     while(t--){
    67         solve();
    68     }
    69     return 0;
    70 }

    D. MEX maximizing

    题意:一个空数组,一个x值,有q次询问,每次询问向数组插入一个值,数组中所有的值可以任意增加n*x倍,减少n*x被,每次询问输出不包含在数组中最小的正整数值。

    思路:一道思维题。每次询问时,把插入的值对x取余,设其为y,意为x可以转移成y,每次记录可以转移到y的数字个数,每次需要y时就查询,这样贪心地进行下去即可,时间复杂度O(n)级别。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 4e5+5;
     4 int v[maxn];
     5 int q,x;
     6 int main(){
     7     scanf("%d%d",&q,&x);
     8     int mex = 0;
     9     while(q--){
    10         int y;scanf("%d",&y);
    11         if((y%x)!=(mex%x)) v[y%x]++;//当前如果不需要 就先记录下来(y%x)的个数
    12         else{
    13             mex++;//否则就消耗掉
    14             while(1){
    15                 if(v[mex%x]) v[mex%x]--,mex++;//查询目前所需要的,如果有就消耗一次,再令mex++
    16                 else break;
    17             }
    18         }
    19         printf("%d
    ",mex);
    20     }
    21     return 0;
    22 }

    E. Obtain a Permutation

    题意:一个n×m的矩阵,矩阵元素的总个数不会超过2e5,有两种操作,1.改变矩阵中任意一元素的值 2.令矩阵的一列所有元素向上移动一格。 求矩阵所有元素恢复成最初位置所需要的最少操作次数

    思路:操作只与列有关,贪心地去枚举每一列。扫描一列地的元素,开一个cnt数组,首先判断一下这个元素是否属于该列,如果属于该列,那么记录他恢复到原有位置需要向上移动多少次,假设需要i次,那么让cnt[i] ++,这样扫描完一列之后,再去找该列恢复原有序列的最小操作次数,ans = min(ans,i+n-cnt[i] ),i是该列所有元素移动次数,n是该列元素的个数,n-cnt[i]就是通过向上移动i次,不能到原有位置的元素,这样只能用操作1来实现了。

     1 #include<bits/stdc++.h>
     2 #define inf 0x3f3f3f3f
     3 using namespace std;
     4 int n,m;
     5 int main(){
     6     scanf("%d%d",&n,&m);
     7     int g[n][m];
     8     for(int i = 0;i<n;i++){
     9         for(int j = 0;j<m;j++){
    10             scanf("%d",&g[i][j]);
    11         }
    12     }
    13     int ans = 0;
    14     for(int i = 0;i<m;i++){
    15         vector<int> cnt(n);
    16         for(int j = 0;j<n;j++) cnt[j] = 0;//初始化cnt数组
    17         for(int j = 0;j<n;j++){
    18             if((g[j][i]-1)%m == i && g[j][i]<=m*n){//如果该元素属于这一列
    19                 int h = (g[j][i]-1)/m ;//计算原有的位置
    20                 int dif = j - h;//计算需要向上移动的次数
    21                 if(dif<0) dif+=n;
    22                 cnt[dif]++;//记录+1
    23             }
    24         }
    25         int t = inf;
    26         for(int j = 0;j<n;j++) t = min(t,j+n-cnt[j]);//找出该列元素回到原有位置需要的最少操作次数
    27         ans+=t;//每一列操作次数都加和
    28     }
    29     printf("%d",ans);
    30     return 0;
    31 }

    F. Three Paths on a Tree

    题意:给出一无权棵树,在树中找到三个结点a,b,c使得a到b到c路径距离最长,如果a到b的路径和a到c的路径有重复,重复的部分不做计算。

    思路:首先树中两点之间最远的距离是树的直径,那么可以用bfs求出树的直径,直径两个端点设为a和b,再用bfs求出其他点到a和b的距离,最后枚举c点即可,这样是最优的,最终答案就等于(dis_ab+dis_bc+dis_ac) / 2。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 2e5+5;
     4 vector<int> G[maxn];
     5 int dis1[maxn],dis2[maxn],dis[maxn],v[maxn];
     6 int n,a,b,c,pos,disab,disac,disbc; 
     7 void bfs(int cur){
     8     queue<int> q;
     9     q.push(cur);
    10     memset(v,0,sizeof(v));
    11     memset(dis,0,sizeof(dis));
    12     v[cur] = 1;
    13     int p = cur,temp = 0;
    14     while(!q.empty()){
    15         int now = q.front();
    16         q.pop();
    17         for(int i = 0;i<G[now].size();i++){
    18             if(v[G[now][i]] == 0){
    19                 v[G[now][i]] = 1;
    20                 q.push(G[now][i]);
    21                 dis[G[now][i]] = dis[now] + 1;//计算距离
    22                 if(dis[G[now][i]] > temp) p = G[now][i],temp = dis[G[now][i]];
    23             }
    24         }
    25     }
    26     pos = p;
    27 }
    28 
    29 int main(){
    30     scanf("%d",&n);
    31     int st;
    32     for(int i = 0;i<n-1;i++){
    33         int u,v;
    34         scanf("%d%d",&u,&v);
    35         st = u;
    36         G[u].push_back(v),G[v].push_back(u);
    37     }
    38     bfs(1);//枚举a
    39     a = pos ;
    40     bfs(a);//枚举b
    41     b = pos;
    42     int t = 0;//两边bfs求出树的直径
    43     for(int i = 1;i<maxn;i++){//求出其他点到a的距离
    44         dis1[i] = dis[i];
    45         if(dis1[i]>t) {
    46             b = i,t = dis1[i],disab = dis1[i];
    47         }
    48     } 
    49     bfs(b);
    50     t = 0;
    51     for(int i = 1;i<maxn;i++){//求出其他点到b的距离
    52         dis2[i] = dis[i];
    53         if(dis1[i]>t) {
    54             t = dis2[i];
    55         }
    56     }
    57     for(int i = 1;i<maxn;i++){
    58         if(dis1[i]+dis2[i] > disac + disbc && i!=a && i!=b){//枚举c点
    59             disac = dis1[i],disbc = dis2[i];
    60             c = i;
    61         }
    62     } 
    63     printf("%d
    ",(disac+disab+disbc)/2);
    64     printf("%d %d %d",a,b,c);
    65     return 0;
    66 }
  • 相关阅读:
    微信小程序代码大全
    【活动发布】捷微H5-微信新年砍价活动,开源发布了
    小程序官网CMS开源项目出炉,Weixin-App-CMS 1.0 版本正式发布
    jeecg开源项目的IDEA的部署
    1024程序员节宅男节日快乐 -- JAVA快速开发平台,JEECG 3.8宅男优化版本发布
    微信小程序商城开源项目,Weixin-App-Shop 1.0 版本正式发布!!!
    JEECG-Swagger UI的使用说明
    JEECG 上传插件升级-代码生成器
    Why 0.1 + 0.2 === 0.30000000000000004 ?
    linux (一)
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12237306.html
Copyright © 2011-2022 走看看