zoukankan      html  css  js  c++  java
  • 2017 清北学堂 Day 6终极考试报告

    预计分数: 100+70+70 = 240

    实际假分数 : 40+80+70= 190  in cena(好吧不得不承认这个分数,,,,,,=.=)

    实际真分数 : 100+80+100 = 280 in luogu.org

    一句话:stl,cena害我一生,,,,,,

    消失的数字(number)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    rsy拥有n个数,这n个数分别是a1,a2,…,an。

    后来出现了一个熊孩子zhw,用橡皮擦去了其中若干个数字,并且打乱了剩下的数字。rsy赶到现场后只剩下了m个数字b1,b2,…,bm,她想知道哪些数字被擦去了。

    现在你需要告诉rsy被擦去的n-m个数是什么。

    输入格式(number.in)

        第一行一个数n,第二行n个数ai,表示一开始的数字。

        第三行一个数m,第四行m个数bi,表示被擦去后的数字。

    输出格式(number.out)

        一行n-m个数,从小到大输出所有被擦去的数字。

    输入样例

    5

    1 3 5 7 8

    3

    3 5 8

    输出样例

    1 7

    数据范围

    对于30%的数据n<=1000,ai与bi都是有序的。

    对于60%的数据n<=100000,ai与bi都是有序的。

    对于80%的数据n<=100000,ai,bi<=n。

    对于100%的数据n<=100000,1<=ai,bi<=10^9。

    一开始傻乎乎的以为这是一眼题,随手敲了个map+栈感觉肯定AC,然后敲了个vector的暴力开始对拍,各种极端极限数据都没问题

    结果!!!!

    我还是高估cena了....

    60分的超时也是醉了。。。。

    在洛谷上最慢的点才700ms,,,,,

    ╮(╯▽╰)╭,,认命,,,,

    正确做法:把两个数组都从小到大排一遍然后在A里把B中出现过得元素都删掉就好

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<cmath>
     8 #include<map>
     9 using namespace std;
    10 int n,m;
    11 int p;
    12 map<int,int>a;
    13 int maxn=-1;
    14 int ans[100001];
    15 int num=1;
    16 int s[100001];
    17 int top=1;
    18 int main()
    19 {
    20     //freopen("number.in","r",stdin);
    21     //freopen("number.out","w",stdout);
    22     scanf("%d",&n);
    23     for(int i=1;i<=n;i++)
    24     {
    25         scanf("%d",&p);
    26         a[p]=a[p]+1;
    27         if(p>maxn)maxn=p;
    28         s[top]=p;top++;
    29     }
    30     scanf("%d",&m);
    31     for(int i=1;i<=m;i++)
    32     {
    33         scanf("%d",&p);
    34         a[p]=a[p]-1;
    35     }
    36     int q=a.size();
    37     while(top!=0)
    38     {
    39         int p=s[top];top--;
    40         if(a[p]!=0)
    41         {
    42             for(int i=1;i<=a[p];i++)
    43             ans[num++]=p;
    44             a[p]=0;
    45         }
    46     }
    47     sort(ans+1,ans+num);
    48     for(int i=1;i<=num-1;i++)
    49     printf("%d ",ans[i]);
    50     return 0;
    51 }
    龟速map+栈
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,m;
     7 int a[100001];
     8 int b[100001];
     9 int num=1;
    10 int main()
    11 {
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++)
    14         scanf("%d",&a[i]);
    15     scanf("%d",&m);
    16     for(int i=1;i<=m;i++)
    17         scanf("%d",&b[i]);
    18     sort(a+1,a+n+1);sort(b+1,b+m+1);
    19     for(int i=1;i<=n;i++)
    20     {
    21         if(a[i]==b[num])
    22         {
    23             a[i]=0;
    24             num++;
    25         }
    26     }
    27     for(int i=1;i<=n;i++)
    28     {
    29         if(a[i]!=0)
    30         {
    31             printf("%d ",a[i]);
    32         }
    33     }
    34     return 0;
    35 }
    AC

    一道数论好题(math)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    rsy最近在研究欧几里得算法,不会的同学可以去看下课件以及代码……

    现在她想到了一个新的问题,求k个数的最大公约数!

    事实上这个问题仍然很简单。所以rsy想强化一下,她觉得最大公约数等于1就不是很有趣了。因此她想在n个数中找最多的数,使得它们的最大公约数不等于1。

    现在rsy想知道,能找最多多少个数。

    输入格式(math.in)

        第一行一个数n。

        第二行n个数ai。

    输出格式(math.out)

        一个数表示答案。

    输入样例

    5

    2 3 4 5 6

    输出样例

    3

    数据范围

    对于30%的数据n<=5。

    对于50%的数据n<=20。

    对于80%的数据n<=1000,ai<=1000。

    对于100%的数据1<=n<=100000,1<=ai<=100000,数据几乎是随机的。

     

    当我读完题立马就意思到- - > 骗分狗又要高兴咯=。=

    为什么累?

    因为这道题是让着求最大公约数

    而偶数(也就是%2==0)是最普遍的最大公约数(因为自然数除了奇数就是偶数)

    so 如果你能想到把%2==0的数的个数统计一下

    那么恭喜你得到70分

    但我还是没有这么不要脸滴

    so我机智的选择用1000以内的素数筛(感觉自己更不要脸)

    然而最后两个点一个莫名其妙的WA一个莫名其妙的TLE.......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<cmath>
     8 using namespace std;
     9 int a[100001];
    10 int num=0;
    11 int vis[100001];
    12 int tot[100001];
    13 int xx[100001];
    14 int js=0;
    15 int main()
    16 {
    17     for(int i=2;i<=sqrt(100000);i++)
    18         if(vis[i]==0)
    19             for(int j=i*i;j<=100000;j=j+i)
    20                 vis[j]=1;
    21     for(int i=1;i<=10000;i++)
    22     if(vis[i]==0)
    23     xx[++js]=i;
    24     int n;
    25     scanf("%d",&n);
    26     for(int i=1;i<=n;i++)
    27     {
    28         int p;
    29         scanf("%d",&p);
    30         a[++num]=p;
    31     }
    32     for(int i=2;i<=js;i++)
    33     {
    34         for(int j=1;j<=num;j++)
    35         {
    36             if(a[j]%xx[i]==0)
    37             tot[xx[i]]++;
    38         }
    39     }
    40     int maxn=0;
    41     for(int i=0;i<js;i++)
    42     {
    43         if(tot[xx[i]]>maxn)
    44         maxn=tot[xx[i]];
    45     }
    46     printf("%d",maxn);
    47     return 0;
    48 }
    80分不知道哪儿错了的代码
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int a[1000001];
     6 int main()
     7 {
     8     int n;
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;i++)
    11     {
    12         int p;
    13         scanf("%d",&p);
    14         a[p]++;
    15     }
    16     int ans=-1;
    17     for(int i=2;i<=100000;i++)
    18     {
    19         int maxnnow=0;
    20         for(int j=i;j<=100000;j=j+i)
    21             maxnnow+=a[j];
    22         if(maxnnow>ans)
    23         ans=maxnnow;
    24     }
    25     printf("%d",ans);
    26     return 0;
    27 }
    AC

    扫雷(mine)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    rsy最近沉迷于一款叫扫雷的游戏。

    这个游戏是这样的。一开始网格上有n*m个位置,其中有一些位置有雷。每次rsy可以左键点击一个方块,此时若这个方块是雷,则rsy被炸,游戏结束,否则如果这个位置周围8格有x个雷,则会显示数字x。特别地,当x=0时,系统会自动左键点击附近8个位置。(此时附近8个位置一定没有雷,假如附近8个位置仍存在x=0,则继续往外扩展)想要更进一步获得关于题目的信息,打开程序->附近->游戏->扫雷或者直接打开下发的可执行文件。

    或者rsy右键点击一个位置,标注这个位置是雷。

    不幸的是,她鼠标不能左右键同时点击,因此只需考虑她左键点击与右键点击就可以了。

    注意游戏胜利的条件是所有非雷的位置都被左键点击到。(特别地,当一开始时n*m个位置都是雷时,LYK自动获得胜利)

    rsy从网上下载了金手指,很轻易地就掌握了所有雷所在的位置。rsy想通过最少的点击次数获得胜利(这里的点击次数不包括系统自动点击)。于是他来请求你的帮助。

    输入格式(mine.in)

        第一行两个数n,m。

        接下来n行,每行m个数ai,j,表示这个矩阵。若ai,j=’*’则表示这个位置是雷,若ai,j=’.’则表示不是雷。

    输出格式(mine.out)

    一个数表示答案。

    输入样例

    3 3

    ..*

    ...

    ..*

    输出样例

    2

    对于30%的数据n=1;

    对于另外20%的数据n,m<=3;

    对于再另外20%的数据*大致占矩阵的2/3且数据随机。

    对于100%的数据n,m<=1000。

    Hint:

    适度游戏益脑,沉迷游戏伤身。ok

     

    一开始看这题还是有些懵逼的,但是手动过了一把扫雷之后就明白了

    只要照着0一顿乱点就可以了呗。。。

    然而!!!!

    因为搜索需要,我机(tou)智(lan)的开了4个queue队列,

    结果,,,,

    最后三个点超时。。。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<cmath>
     8 using namespace std;
     9 int n,m;
    10 int a[1001][1001];
    11 int vis[1001][1001];
    12 char p;
    13 int xx[10]={-1,+1,0,0,-1,-1,+1,+1};
    14 int yy[10]={0,0,-1,+1,-1,+1,-1,+1};
    15 queue<int>qx;
    16 queue<int>qy;
    17 int ans=0;
    18 void deal(int nowx,int nowy)
    19 {
    20     queue<int>needx;
    21     queue<int>needy;
    22     needx.push(nowx);
    23     needy.push(nowy);
    24     while(needx.size()!=0&&needy.size()!=0)
    25     {
    26         int nowneedx=needx.front();needx.pop();//当前为0的元素 
    27         int nowneedy=needy.front();needy.pop();
    28         for(int i=0;i<8;i++)
    29         {
    30             int wx=nowneedx+xx[i];
    31             int wy=nowneedy+yy[i];
    32             if(wx>=1&&wx<=n&&wy>=1&&wy<=m)
    33             {
    34                 if(a[wx][wy]==0&&vis[wx][wy]==0)
    35                 {
    36                     needx.push(wx);
    37                     needy.push(wy);
    38                 }
    39                 vis[wx][wy]=1;
    40             }
    41                 
    42         }
    43     }
    44         
    45 }
    46 int main()
    47 {
    48     scanf("%d%d",&n,&m);
    49     for(int i=1;i<=n;i++)
    50         for(int j=1;j<=m;j++)
    51         {cin>>p;    if(p=='*')    a[i][j]=438;}
    52     for(int i=1;i<=n;i++)
    53     {
    54         for(int j=1;j<=m;j++)
    55         {
    56             for(int k=0;k<8;k++)
    57             {
    58                 if(a[i][j]!=438&&a[i+xx[k]][j+yy[k]]==438&&i+xx[k]>=1&&i+xx[k]<=n&&j+yy[k]>=1&&j+yy[k]<=m)
    59                 a[i][j]++;
    60             }
    61             if(a[i][j]==0&&vis[i][j]==0)
    62             {qx.push(i);qy.push(j);vis[i][j]=1;}
    63         }
    64     }
    65     memset(vis,0,sizeof(vis));
    66     while(qx.size()!=0&&qy.size()!=0)
    67     {
    68         int nowx=qx.front();qx.pop();
    69         int nowy=qy.front();qy.pop();
    70         if(vis[nowx][nowy]==0)
    71         {
    72             ans++;
    73             vis[nowx][nowy]=1;
    74             deal(nowx,nowy);
    75         }
    76     }
    77     for(int i=1;i<=n;i++)
    78     {
    79         for(int j=1;j<=m;j++)
    80         {
    81             if(vis[i][j]==0&&a[i][j]!=438)
    82             ans++;
    83         }
    84     }
    85     printf("%d",ans);
    86     return 0;
    87 }
    开了4个queue不想改反正在洛谷AC的代码

    总结:这次考试终于发挥出真正水平了,但成绩仍然一般,,。,。虽然原因很多吧,但是也反映出了我的很多弱点:

    1.思路太窄,第一题明明可以想到O(n*m)的做法,但是自己还是明知map慢偏用map做,其实有时候完全可以不用使劲照着一种思路走到死胡同,说不定换个角度就是海阔天空呢?

    2.对极限和极端数据的分析不够深入,特别是在写对拍的时候,一定不要只注意程序在极限数据的结果,必须要先确保程序的运行时间在允许范围之内!

  • 相关阅读:
    查找mysql数据库中所有包含特定名字的字段所在的表
    redis在windows下安装和PHP中使用
    CentOS 6.3下源码安装LAMP(Linux+Apache+Mysql+Php)环境
    telnet: connect to address 127.0.0.1: Connection refused
    [Java]局域网五子棋
    springboot-web进阶(三)——统一异常处理
    springboot-web进阶(二)——AOP统一处理请求
    springboot-web进阶(一)——表单验证
    springboot快速入门(五)——事务管理
    springboot快速入门(四)——数据库操作
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6803743.html
Copyright © 2011-2022 走看看