• 题解 Codeforces Round #615 (Div. 3) (CF1294)


    A:判断一下和是不是3的倍数,由于只加不减,所以还要判断有没有大于和的1/3。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define it register int
     5 #define ct const int
     6 #define il inline
     7 using namespace std;
     8 int T,a,b,c,n,x;
     9 namespace io{
    10     il char nc(){
    11         static char buf[100000],*p1=buf,*p2=buf;
    12         return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    13     }
    14     template <class I> 
    15     il void fr(I &num){
    16         num=0;register char c=nc();it p=1;
    17         while(c<'0'||c>'9') c=='-'?p=-1,c=nc():c=nc();
    18         while(c>='0'&&c<='9') num=num*10+c-'0',c=nc();
    19         num*=p;
    20     } 
    21 };
    22 using io :: fr;
    23 int main(){
    24     fr(T);
    25     while(T--){
    26         fr(a),fr(b),fr(c),fr(n);
    27         if((a+b+c+n)%3){puts("NO");continue;}
    28         x=(a+b+c+n)/3;
    29         if(a>x||b>x||c>x){puts("NO");continue;}
    30         puts("YES");
    31     }
    32     return 0;
    33 }
    View Code

    B:发现只能向上和向右。所以我们必须保证序列在两维上非降。那么按照x,y升序排序,然后判断一下对于这个点是否存在x比它的x小且y比它的y大,有就是无解。由于字典序要小,所以肯定先右“R”再上“U”。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define it register int
     5 #define ct const int
     6 #define il inline
     7 using namespace std;
     8 const int N=100005;
     9 int T,n,lastx,lasty;
    10 bool flag;
    11 struct ky{
    12     int x,y;
    13 }a[N];
    14 bool cmp(ky p,ky q){
    15     return p.x^q.x?p.x<q.x:p.y<q.y;
    16 }
    17 int main(){
    18     scanf("%d",&T);it i;
    19     while(T--){
    20         scanf("%d",&n);
    21         for(i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y);
    22         std::sort(a+1,a+1+n,cmp);
    23         flag=0;
    24         for(i=1;i<=n;++i)
    25             if(a[i].x!=a[i-1].x&&a[i].y<a[i-1].y) flag=1,i=n+1;
    26         if(flag){puts("NO");continue;}
    27         lastx=0,lasty=0,puts("YES");
    28         for(i=1;i<=n;++i){
    29             for(it j=lastx;j<a[i].x;++j) putchar('R');
    30             for(it j=lasty;j<a[i].y;++j) putchar('U');
    31             lastx=a[i].x,lasty=a[i].y;
    32         }
    33         putchar('
    ');
    34     }
    35     return 0;
    36 }
    View Code

    C:先在√n时间内算出n的因子个数,判断是否有解,注意除去n的1与本身这两个因子。在有解的情况下找出两个小于√n的一个大于√n的(若有解肯定存在)即可。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define it register int
     5 #define ct const int
     6 #define il inline
     7 using namespace std;
     8 int T,a,b,c,n,x,ans1,ans2,ans3;
     9 namespace io{
    10     il char nc(){
    11         static char buf[100000],*p1=buf,*p2=buf;
    12         return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    13     }
    14     template <class I> 
    15     il void fr(I &num){
    16         num=0;register char c=nc();it p=1;
    17         while(c<'0'||c>'9') c=='-'?p=-1,c=nc():c=nc();
    18         while(c>='0'&&c<='9') num=num*10+c-'0',c=nc();
    19         num*=p;
    20     } 
    21 };
    22 using io :: fr;
    23 int main(){
    24     fr(T);it i;register long long now=1;
    25     while(T--){
    26         fr(n);
    27         it x=n,cnt=0;now=1;
    28         for(i=2;i*i<=x;++i)
    29             if(!(x%i)){
    30                 cnt=0;
    31                 while(!(x%i))
    32                     x/=i,++cnt;
    33                 now*=(cnt+1ll);
    34             }
    35         if(x>1) now<<=1;
    36         now-=2;
    37         if(now<3){puts("NO");continue;}
    38         x=n,cnt=0,ans1=ans2=0;
    39         for(i=2;cnt<2&&i*i<=x;++i)
    40             if(!(x%i))
    41                 ++cnt,x/=i,cnt==1?ans1=i:(cnt==2?ans2=i:ans3=i);
    42         if(cnt==2&&x>ans2&&ans2)
    43             puts("YES"),printf("%d %d %d
    ",ans1,ans2,x);
    44         else puts("NO");
    45     }
    46     return 0;
    47 }
    View Code

    D:构建mod x的剩余系,每次找到这个剩余系里面最大的加上x即可。注意到最多进行n次操作,所以>=n的其实没啥意义。然后怎么找第一个未出现过的元素:很显然按照我的添加方法肯定每个数只出现一次。所以维护一个set,只要每次把出现过的删掉,输出s.begin()(第一个元素也就是最小的没被删掉的,即还没出现的)即可。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<bitset>
     4 #include<set>
     5 #include<algorithm>
     6 #define it register int
     7 #define ct const int
     8 #define il inline
     9 using namespace std;
    10 const int N=1000005;
    11 int T,a,b,c,n,x,f[N],maxn;
    12 set<int> s;
    13 namespace io{
    14     il char nc(){
    15         static char buf[100000],*p1=buf,*p2=buf;
    16         return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    17     }
    18     template <class I> 
    19     il void fr(I &num){
    20         num=0;register char c=nc();it p=1;
    21         while(c<'0'||c>'9') c=='-'?p=-1,c=nc():c=nc();
    22         while(c>='0'&&c<='9') num=num*10+c-'0',c=nc();
    23         num*=p;
    24     } 
    25 };
    26 using io :: fr;
    27 bitset<N> vs;
    28 int main(){
    29     fr(n),fr(x);it i,nowmax=-1,y;maxn=-1;
    30     for(i=0;i<x;++i) f[i]=-1;
    31     for(i=0;i<=n;++i) s.insert(i);
    32     for(i=1;i<=n;++i){
    33         fr(y),y%=x;
    34         f[y]==-1?f[y]=y:f[y]+=x;
    35         if(f[y]<=400000) s.erase(f[y]);
    36         printf("%d
    ",*s.begin());
    37     }
    38     return 0;
    39 }
    View Code

    E:每一列互不相关,所以可以枚举每一列单独考虑。因为我们可以移动和重置,有的数可以移动但有的必须重置。假设x为第i行j列的数,如果(x+m-1)/m<=n&&x%m==j%m,说明x移动到最终矩阵中的位置的最小次数是(i-(x+m-1)/m+n)%n(+n再%n是为了处理负数)。所以我们把每个最小次数用桶记下来这个最小次数的出现次数,然后枚举最小次数i,求这一列需要的最小次数ans=Min(ans,i+n-s[i]),然后把ans累计入答案。

     1 #include<stdio.h>
     2 #include<vector>
     3 #include<algorithm>
     4 #define it register int
     5 #define ct const int
     6 #define il inline
     7 using namespace std;
     8 const int N=200005;
     9 vector<int> a[N];
    10 int s[N],o,n,m;
    11 il int Min(ct p,ct q){return p<q?p:q;}
    12 namespace io{
    13     il char nc(){
    14         static char buf[100000],*p1=buf,*p2=buf;
    15         return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    16     }
    17     template <class I> 
    18     il void fr(I &num){
    19         num=0;register char c=nc();it p=1;
    20         while(c<'0'||c>'9') c=='-'?p=-1,c=nc():c=nc();
    21         while(c>='0'&&c<='9') num=num*10+c-'0',c=nc();
    22         num*=p;
    23     } 
    24 }
    25 using io :: fr;
    26 void solve(ct x){
    27     it i,ans=n;
    28     for(i=0;i<=n;++i) s[i]=0;
    29     for(i=1;i<=n;++i)
    30         if(a[x][i]%m==x%m&&(a[x][i]+m-1)/m<=n) ++s[(i-(a[x][i]+m-1)/m+n)%n];
    31     for(i=0;i<=n;++i) ans=Min(ans,i+n-s[i]);
    32     o+=ans;
    33 }
    34 int main(){
    35     fr(n),fr(m);it i,j,x;
    36     for(i=1;i<=m;++i) a[i].push_back(0);
    37     for(i=1;i<=n;++i)
    38         for(j=1;j<=m;++j) 
    39             fr(x),a[j].push_back(x);
    40     for(i=1;i<=m;++i) solve(i);
    41     printf("%d",o);
    42     return 0;
    43 }
    View Code

    F:明明还剩00:01:06的时候交F可是没交上去呜呜呜。思路是先以1为根找出深度最大的mx1,再以mx1为根找出深度最大的mx2,然后沿着这条路把路上的点标记一下,再找到深度最大的mx3。每次找的时候ans++记录路径长度。由于x个点会有x-1条路,所以最后答案为ans-1.

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<bitset>
     4 #include<algorithm>
     5 #define it register int
     6 #define ct const int
     7 #define il inline
     8 using namespace std;
     9 const int N=1000005;
    10 int h[N],nxt[N],adj[N],fa[N],ans,mx1,mx2,mx3,u,v,n,m,t,id,d[N];
    11 bitset<N> vs;
    12 namespace io{
    13     il char nc(){
    14         static char buf[100000],*p1=buf,*p2=buf;
    15         return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    16     }
    17     template <class I> 
    18     il void fr(I &num){
    19         num=0;register char c=nc();it p=1;
    20         while(c<'0'||c>'9') c=='-'?p=-1,c=nc():c=nc();
    21         while(c>='0'&&c<='9') num=num*10+c-'0',c=nc();
    22         num*=p;
    23     } 
    24 }
    25 using io :: fr;
    26 il void dfs(ct x){
    27     d[x]=(vs[x]?1:d[fa[x]]+1);
    28     for(it i=h[x],j;i;i=nxt[i])
    29         if((j=adj[i])!=fa[x])
    30             fa[j]=x,dfs(j);
    31 }
    32 il void add(){
    33     nxt[++t]=h[u],h[u]=t,adj[t]=v,nxt[++t]=h[v],h[v]=t,adj[t]=u;
    34 }
    35 int main(){
    36     fr(n);it i;
    37     for(i=1;i<n;++i) fr(u),fr(v),add();
    38     dfs(1);
    39     for(i=1;i<=n;++i){fa[i]=0;if(d[i]>d[mx1]) mx1=i;}
    40     dfs(mx1);
    41     for(i=1;i<=n;++i) if(d[i]>d[mx2]&&i!=mx1)mx2=i;
    42     for(i=mx2;i;i=fa[i]) vs[i]=1,++ans;
    43     dfs(mx1);
    44     for(i=1;i<=n;++i) if(d[i]>d[mx3]&&i!=mx1&&i!=mx2)mx3=i;
    45     for(i=mx3;!vs[i];i=fa[i]) vs[i]=1,++ans;
    46     printf("%d
    %d %d %d",ans-1,mx1,mx2,mx3);
    47     return 0;
    48 }
    View Code

    由于博主已经意识模糊,所以可能会有一些纰漏,请大家指出,谢谢。

    这次唯一的收获大概就是一题没挂,于是用大号刷高了小号的rating(雾

    大号打Div3不能增加Rating了QAQ,但为了好看还是用小号去刷大号正确率,结果每次都是一遍A,然后提高了小号的Rating……

  • 相关阅读:
    PHP的文件下载
    ajax异步请求分页显示
    Linux的启动过程
    搭建nginx反向代理用做内网域名转发
    intellij idea 修改背景保护色&&修改字体&&快捷键大全
    IDEA入门级使用教程-
    http://blog.csdn.net/baidu_31657889/article/details/52315902
    JVM——Java虚拟机架构
    MySQL远程连接ERROR 2003 (HY000):Can't connect to MySQL server on'XXXXX'(111) 的问题
    windows上 nginx 配置代理服务,配置多域名,以及最简单实现跨域配置
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/12230069.html
Copyright © 2020-2023  润新知