zoukankan      html  css  js  c++  java
  • GALAXY OJ NOIP2019联合测试1-总结

     概要

        本次比赛考的不是很好,400分的题只拿了180分。。。(失误失误

     题目

        T1:数你太美(预期100  实际60)

             题目大意:

              在两个序列中找两个最小的数进行组合,使这个最小整数最小。

            解析:

              只要根据题目模拟就可以了。。。。。。。

              (玄学60分!!!)

            code :

                60分代码

                

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int n,m;
     5 int a[100000];
     6 int b[100000];
     7 int main()
     8 {
     9     cin>>n>>m;
    10     int minn=2e9,minm=2e9;
    11     for(int i=1;i<=n;i++)
    12     {
    13         cin>>a[i];
    14         if(minn>a[i])
    15         {
    16             minn=a[i];
    17         }
    18     }
    19     for(int j=1;j<=m;j++)
    20     {
    21         cin>>b[j];
    22         if(minm>b[j])
    23         {
    24             minm=b[j];
    25         }
    26     }
    27     if(minn==minm)
    28     {
    29         cout<<minn;
    30         return 0;
    31     }
    32     else
    33     {
    34         cout<<min(minn*10+minm,minm*10+minn);
    35     }
    36     return 0;
    37 }

                AC代码

     

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 int n,m;
     5 int a[10],b[10];
     6 int at[10],bt[10],ct[10];
     7 int t1,t2;
     8 void cmp(int x,int y)
     9 {
    10     if(x<y)
    11     {
    12         printf("%d",x);
    13     }
    14     else
    15     {
    16         printf("%d",y);
    17     }
    18 }
    19 int main()
    20 {
    21     scanf("%d%d",&n,&m);
    22     for(int i=1;i<=n;i++)
    23     {
    24         scanf("%d",&a[i]);
    25         at[a[i]]=1;
    26     }
    27     for(int i=1;i<=m;i++)
    28     {
    29         scanf("%d",&b[i]);
    30         bt[b[i]]=1;
    31     }
    32     for(int i=0;i<10;i++)
    33     {
    34         ct[i]=at[i]+bt[i];
    35     }
    36     sort(a+1,a+n+1);
    37     sort(b+1,b+m+1);
    38     for(int i=0;i<10;i++)
    39     {
    40         if(ct[i]==2)
    41         {
    42             printf("%d",i);
    43             return 0;
    44         }
    45     }
    46     t1=a[1]*10+b[1];
    47     t2=b[1]*10+a[1];
    48     cmp(t1,t2);
    49     return 0;
    50 }

           T2:逃亡(预期100  实际100)

               题目大意:

                  在(xi,yi)中找到x或y的最短路

               解析:

                  如题;

                 code

                  

     1 #include<cstdio>
     2 using namespace std;
     3 int n,m,k;
     4 int x,y;
     5 double sum=0;
     6 int min(int a,int b)
     7 {
     8     if(a<b)
     9     {
    10         return a;
    11     }
    12     else
    13     {
    14         return b;
    15     }
    16 }
    17 int main()
    18 {
    19     scanf("%d%d%d",&n,&m,&k);
    20     for(int i=1;i<=k;i++)
    21     {
    22         scanf("%d%d",&x,&y);
    23         int t1=min(x,n-x);
    24         int t2=min(y,m-y);
    25         sum+=min(t1,t2);
    26     }
    27     printf("%.3lf",sum);
    28     return 0;
    29 } 

                T3:数数字(预期20  实际20)

                          题目大意:

                      第i个蒟蒻会告诉你他看到了ai种数字(定义两个数字不同种当且仅当它们的值不同)

                          但是由于蒟蒻太弱了,可能会报错数据,NTF需要核实是否有一种情况使所有蒟蒻说的话都正确。

                      这是个题;

                解析:

                    令总的卡片种类为 T,对于每一只蒟蒻,若它的卡片数值唯一则他所看到的卡片种类总
                    数为T-1,否则为T,我们称卡片数值唯一的蒟蒻是孤独的。
                    故若 ai 的最大值和最小值的差大于等于 2 则无解
                    下面对最大值和最小值的差进行分类讨论:
                     若 max=min,那么此时每只蒟蒻看到的卡片种类都为 T 或者都为 T-1。如果每只蒟蒻看到的
                    卡片种类的总数都是 T-1,则每只蒟蒻都是孤独的,此时 T=n。 否则每只蒟蒻所看到的卡片
                      种类的总数都是 T,由于不存在孤独的蒟蒻,所以 T 至多为⌊n/2⌊
                      若 max=min+1,此时我们可以统计孤独的蒟蒻的个数 x,类似上面的推论, 数值总数至少为
                      x+1,至多为 x+⌊(n-x)/2⌊。故当 max=min+1 时, x+1Tx+⌊(n-x)/2⌊
                  

                    code

                      

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 typedef long long ll;
     5 int t;
     6 int n;
     7 int a[10000050];
     8 int only;
     9 int sum;
    10 //inline int read(){
    11 //    char ch=getchar();
    12 //    ll x=0;
    13 //    ll f=1;
    14 //    while(ch<'0'||ch>'9'){
    15 //        if(ch=='-')
    16 //            f=-1;
    17 //        ch=getchar();
    18 //    }
    19 //    while('0'<=ch&&ch<='9'){
    20 //        x=x*10+ch-'0';
    21 //        ch=getchar();
    22 //    }
    23 //    return x*f;
    24 //}
    25 int main()
    26 {
    27     scanf("%d",&t);
    28     while(t--)
    29     {
    30         scanf("%d",&n);
    31         int maxn=-1;
    32         int minm=2e9;
    33         only=0;
    34         sum=0;
    35         for(int i=1;i<=n;i++)
    36         {
    37             scanf("%d",&a[i]);
    38             if(maxn<a[i])
    39                 maxn=a[i];
    40             if(minm>a[i])
    41                 minm=a[i];
    42         }
    43         for(int i=1;i<=n;i++)
    44             if(a[i]==minm) only++;
    45         if(maxn-minm>=2)
    46         {
    47             printf("no
    ");
    48             continue;
    49         }
    50         if(minm==maxn)
    51         {
    52             if(maxn<=n/2||maxn+1==n)
    53             {
    54                 printf("yes
    ");
    55                 continue;
    56             }
    57             printf("no
    ");
    58             continue;
    59         }
    60         if(maxn==minm+1)
    61         {
    62             if(only+1<=maxn&&maxn<=(n-only)/2+only)
    63             {
    64                 printf("yes
    ");
    65             }
    66             else
    67             {
    68                 printf("no
    ");
    69             }
    70         }
    71     }
    72     return 0;
    73 }

            T4:tower(期望得分0  实际得分0);

                    题目大意:

                        

    欲穷千里目,更上一层楼。

    阿克先生喜欢旅游。某一天,他来到魔法森林旅游。

    经过观察,他发现魔法森林一共有​n个城市,每个城市有一座高高的魔法塔,第i​个城市的魔法塔的高度为hi​。这些城市一共由​n-1条道路连接,任意两座城市互相可达。

    阿克先生想要站在某一座塔上观察尽可能多城市的风景。不幸的是,阿克先生没有透视眼,较高的塔将会遮蔽较低的塔。同时,魔法森林其他地方也被茂林覆盖,他的视线无法穿过茂林(但因为是魔法塔,塔上储存了镜面魔法,可以使阿克先生的视线在城市水平任意角度转弯)。

    所以,他只能沿着n-1​条道路观察其他的点。

    但是,魔法森林的道路蜿蜒曲折,他观看的城市到他所在的点的路径要么互相包含要么两两不交。且从他所在的点开始,到任意它观察的城市,所成的高度序列单调不增。

    阿克先生想要知道他最多能观察到多少个城市(包括自身),他快速地秒了这道题,但他懒得写代码了,所以请你帮他算一算。

                        解析:

        30%
        枚举阿克先生在哪个点,然后 dfs, 时间复杂度 O(n^2)
        20%
        从左往右扫一遍,从右往左扫一遍, 计算出每个点向左、向右最长不上升的长度, 然后加在
        一起取 max 就是答案了。 时间复杂度 O(n)
        20%h 互不相同
        观察到若 u 能够观察 v,则 v 一定不能观察 u, 所以按高度从小到大排序,依次加入,维护
        每个点所能伸出的最长链即可; 或者可以直接记忆化搜索。 时间复杂度 O(n log n)O(n)
        100%
        先固定一个点为根, 可以发现,答案的贡献被分为两类:子树内和子树外, dfs 一次,计算
        出每个点在它子树内能延伸出的最长路径和次长路径,再计算每个点以他为所在节点在子树
        内最多覆盖多少个点, 重新 dfs 一次,同时记录它往他父亲延伸最多能延伸多长, 每次向下
        走一格,要么是原路径+1,要么是它兄弟的一个路径,取 max, 如果父亲>儿子,则伸向父
        亲的长度清零, 每个节点的答案就是它子树内的答案+伸向他父亲的最长路径。 时间复杂度
        O(n)

          code

          

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 int tot=0;
     6 int h[5000005];
     7 int s[5000005];
     8 int f[5000005],f1[5000005];
     9 int a[5000005];
    10 int ans=0;
    11 struct edge {
    12     int to,next;
    13 } e[5000005];
    14 void add(int x,int y) {
    15     e[++tot].to=y;
    16     e[tot].next=h[x];
    17     h[x]=tot;
    18 }
    19 void dfs1(int u,int fa) {
    20     s[u]=1,f[u]=1;
    21     for(int i=h[u]; i!=0; i=e[i].next) {
    22         int v=e[i].to;
    23         if (v==fa) continue;
    24         dfs1(v,u);
    25         if (a[u]>=a[v]) {
    26             if (f[u]<f[v]+1) {
    27                 f1[u]=f[u];
    28                 f[u]=f[v]+1;
    29             } else f1[u]=max(f1[u],f[v]+1);
    30             s[u]+=f[v];
    31         }
    32     }
    33 }
    34 void dfs2(int u,int fa,int up) {
    35     ans=max(ans,up+s[u]);
    36     for (int i=h[u]; i!=0; i=e[i].next) {
    37         int v=e[i].to;
    38         if (v==fa) continue;
    39         if (a[v]<a[u])
    40             dfs2(v,u,0);
    41         else {
    42             if(f[v]+1==f[u])
    43                 dfs2(v,u,max(up+1,f1[u]));
    44             else
    45                 dfs2(v,u,max(up+1,f[u]));
    46         }
    47     }
    48 }
    49 int main() {
    50     int n;
    51     tot=0,ans=0;
    52     scanf("%d",&n);
    53     for (int i=1; i<=n; i++)
    54         scanf("%d",&a[i]);
    55     for (int i=1; i<n; i++) {
    56         int q,p;
    57         scanf("%d%d",&q,&p);
    58         add(q,p),add(p,q);
    59     }
    60     dfs1(1,0);
    61     dfs2(1,0,0);
    62     printf("%d
    ",ans);
    63 }

          最后附上oj链接:www.gdfzoj.com

  • 相关阅读:
    词法分析
    HTTP学习笔记
    Servlet入门
    UDP与TCP的区别
    C语言实现血型查询系统
    Mysql的索引、回表查询及覆盖索引浅析
    ReentranLock浅析
    CAS是个什么鬼?
    synchronize和volatile 小知识点总结
    写一个简单的阻塞队列
  • 原文地址:https://www.cnblogs.com/WestJackson/p/11511375.html
Copyright © 2011-2022 走看看