zoukankan      html  css  js  c++  java
  • 牛客小白月赛16

     


    G-小石的图形

    链接:https://ac.nowcoder.com/acm/contest/949/G
    来源:牛客网

    题目描述

    小石想在一面墙旁边建造一段长度为 n 的篱笆来围出一块地(如图)。



    求最大的地的面积。

    输入描述:

    共一行,输入一个整数 n 。

    输出描述:

    共一行,输出最大面积,保留 3 位小数。

    示例1

    输入

    1

    输出

    0.159

    备注:

    0n103

    一看就是水题,上网搜了下π的取值,3.1415926535898,同学用的3.1415926wa掉了

    发现半圆时面积最大(显然)。 n=πR,R=n/π
    面积S=πR2/2=n2/2π

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <math.h>
     4 #include <algorithm>
     5 using namespace std;
     6 #define PI 3.1415926535898
     7  
     8 int main()
     9 {
    10     int n;
    11     scanf("%d",&n);
    12     printf("%.3f
    ",pow(n,2)/(2*PI));
    13     return 0;
    14 }

    E-小雨的矩阵

    链接:https://ac.nowcoder.com/acm/contest/949/E
    来源:牛客网

    题目描述

    小雨有一个 n×n 的矩阵,起点在(1,1),终点在(n,n),只能向下或向右走,且每次只能走 1 步。矩阵上每个点都有一个点权 ai,j
    求走到终点的路径有多少不同的点权和。

    输入描述:

    第一行,输入一个正整数 n 。
    接下来 n+1 行,每行 n 个数,表示 ai,j

    输出描述:

    共一行,输出有多少不同的点权和。

    示例1

    输入

    2
    1 5
    2 4

    输出

    2

    说明

    (1,1)(2,1)(2,2)7(1,1)(1,2)(2,2)10

    备注:

    1n8,0ai,j50

    刚开始以为很难,后来发现也就是一道水题,从(1,1)爆搜到(n,n),把答案去一下重即可。

    用DFS,结果存到set中就好了

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <set>
     4 using namespace std;
     5  
     6 int N[9][9];
     7 int T[2][2]={{0,1},{1,0}};
     8 int vis[9][9];
     9 int n;
    10  
    11 set<int> st;
    12  
    13 void DFS(int x,int y,int sum)
    14 {
    15      
    16     if(x==n&&y==n)
    17     {
    18         st.insert(sum);
    19         return;
    20     }
    21     for(int i=0;i<2;i++)
    22     {
    23         int a=x+T[i][0];
    24         int b=y+T[i][1];
    25         if(a<1||b<1||a>n||b>n)
    26             continue;
    27         if(!vis[a][b])
    28         {
    29             vis[a][b]=1;
    30             DFS(a,b,sum+N[a][b]);
    31             vis[a][b]=0;
    32         }
    33     }
    34     return;
    35 }
    36  
    37 int main()
    38 {
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++)
    41     {
    42         for(int j=1;j<=n;j++)
    43         {
    44             scanf("%d",&N[i][j]);      
    45         }
    46     }
    47     DFS(1,1,N[1][1]);
    48     printf("%d",st.size());
    49     return 0;
    50 }

    A-小石的签到题

    链接:https://ac.nowcoder.com/acm/contest/949/A
    来源:牛客网

    题目描述

    小石和小阳玩游戏,一共有 n个数,分别为 1n。两人轮流取数,小石先手。对于每轮取数,都必须选择剩下数中的任意一个数 x,同时还要取走 x,x/2,x/2⌋/2… 如果某个数不存在,就停止取数(不能一个数都不取)。
    谁取走最后一个数,谁就输了。小石想知道自己能否获胜。 如果小石能赢,输出 “Shi”,否则输出 "Yang”(均不输出引号)。

    输入描述:

    共一行,输入一个数 n

    输出描述:

    共一行,输出 "Shi" 或 "Yang"(不输出引号)。

    示例1

    输入

    1

    输出

    Yang

    说明

    小石只能取走 1,小阳赢。

    示例2

    输入

    2

    输出

    Shi

    说明

    若小石取走 1,则小阳只能取走 2,小石赢。

    备注:

    1n109

    第一题看到别人几分钟就做出来了,很是懵逼,想不出为什么呀。。。估计可能是规律题,要猜猜

    第一次是猜奇数小阳赢,偶数小石赢,错了。

    后来发现当 n>1 时先手(小石)总是赢。如何证明:一开始有 1n , n 个数,假设先手必败,那么先手选 1,后手就进入了必败状态。
    所以假设错误,那么先手就不是必败,先手一定有一种方式能赢。

     怪不得有人四十多秒就做出来。。

     1 #include<stdio.h>
     2 
     3 int main()
     4 {
     5     int n;
     6     scanf("%d",&n);
     7     if(n==1)
     8         printf("Yang
    ");
     9     else
    10         printf("Shi
    ");
    11     return 0;
    12 }

    C-小石的海岛之旅

    链接:https://ac.nowcoder.com/acm/contest/949/C
    来源:牛客网

    题目描述

    暑假到了,小石和小雨到海岛上玩。
    从水平方向看海岛可以看成 n个小块,每一个小块都有一个高度hi
    水位一开始为 0,随着水位的上升,海岛分成了若干块。
    现在有 m 个询问,求当水位为ai 时,海岛会分成多少块。
     

    输入描述:

    第一行输入两个正整数n,m,分别表示海岛小块个数和询问个数。
    第二行输入 n 个整数 hi,表示每一块的高度。
    第三行输入 m个整数 ai,表示每一个询问,保证输入的 ai 单调递增。

    输出描述:

    共 m 行,分别对应 m 个询问的答案。

    示例1

    输入

    7 3
    1 2 3 1 2 1 3
    1 2 3

    输出

    3
    2
    0

    说明

    当水位高度为 1 时,岛屿被分成 3 块,2 3;2;3

    当水位高度为 2 时,岛屿被分成 2 块:3;3 。

    当水位高度为 3 时,岛屿全部被淹没,剩余 0 块 。

    备注:

    1n,m103,1hi109,1ai<ai+1109

    我们按海岛的高度 hi 从大到小排序。
    假设海岛i在水位为 ai 时被淹没,如果海岛 i1 和海岛 i+1 都已被淹没,那么就少了一块,答案减 1 。
    如果海岛 i1 和海岛 i+1 都没被淹没,那么一块变两块,答案加 1 。
    否则答案不变。
    由于出题人良心,直接N2是能过的。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <queue>
     8 using namespace std;
     9 #define maxn 1002
    10 int D[maxn];
    11 int F[maxn];
    12 int main()
    13 {
    14     //freopen("sample.txt","r",stdin);
    15     int n,m;
    16     scanf("%d %d",&n,&m);
    17     for(int i=1;i<=n;i++)
    18     {
    19         scanf("%d",&D[i]); 
    20     }
    21     memset(F,1,sizeof(F));
    22     F[n+1]=0;
    23     for(int i=0;i<m;i++)
    24     {
    25         int t;
    26         scanf("%d",&t);
    27         for(int j=1;j<=n;j++)
    28         {
    29             if(F[j]&&D[j]<=t)
    30             {
    31                 F[j]=0;
    32             }
    33         }
    34         int tot=0;
    35         for(int j=1;j<=n;j++)
    36         {
    37             if(F[j]&&!F[j+1])
    38             {
    39                 tot++;
    40             }
    41         }
    42         printf("%d
    ",tot);
    43     }
    44     return 0;
    45 }

    B-小雨的三角形

    链接:https://ac.nowcoder.com/acm/contest/949/B
    来源:牛客网

    题目描述

    小雨手上有一个填满了数字的三角形。这个三角形一共有 n 层,其中第 i 层共有 i个数,且第 1 个数和第 i 个数均为 i 。
    其余的数中,第 j 个数是上一层中第 j−1 个数和第 j 个数的和。小雨想知道这个三角形第 x 层到第 y 层所有数的和,一共有 m 个询问。

    输入描述:

    第一行两个正整数 n,m,表示这个三角形的层数和询问个数。
    接下来 m 行,每行两个正整数 x,y,表示一次询问。

    输出描述:

    输出共 m 行,每行一个整数,表示一组询问的答案,对 109+7 取模。

    示例1

    输入

    5 3
    1 2
    1 5
    3 5

    输出

    5
    83
    78

    说明

    画出这个三角形:
    1
    2 2
    3 4 3
    4 7 7 4
    5 11 14 11 5
    第 12 层的和为 1+2+2=5
    第 15 层的和为 1+2+2+3+4+3+4+7+7+4+5+11+14+11+5=83
    第 35 层的和为 3+4+3+4+7+7+4+5+11+14+11+5=78 。

    备注:

    1n103,1m103,1xyn

    神坑题,错了好多次,做题不规范,赛后两行泪,注意,数据可能会溢出,而且要优化算法,减少算法复杂度,防止时间超限和数据溢出导致的wa

    数据范围给的很小,可以 O(n2) 暴力构造三角形,预处理出每一行的总和,每个询问把 x∼y 行的和加起来即可(若预处理出第 1∼i 行的和,则可以做到 O(1) 查询)。
    更快的做法?每一行的和其实是有规律的,分别为 1,4,10,22,46,94⋯,除了第 11 行的和为 11 外,第 ii行的和为 62i22,那么第 1i (i>1)行的和为

     1+6202+6222+6232++62i22=1+6(2i11)2(i1)=62i12i3 

    所以第 xy 行的和就能用前缀和计算了,注意特判 x=1,x=2,y=1 的情况,这样就能够每次 O(log⁡n) 查询。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <queue>
     8 using namespace std;
     9 #define maxn 1001
    10 long long dp[maxn];
    11  
    12 int main()
    13 {
    14     //freopen("sample.txt","r",stdin);
    15     int n,m;
    16     scanf("%d %d",&n,&m);
    17     dp[1]=1;
    18     for(int i=2;i<=n;i++)
    19     {
    20         dp[i]=(dp[i-1]*2+2)%(long long)(pow(10,9)+7);
    21     }
    22     for(int i=0;i<m;i++)
    23     {
    24         int a,b;
    25         scanf("%d %d",&a,&b);
    26         long long sum=0;
    27         for(int g=a;g<=b;g++)
    28         {
    29             sum=(sum+dp[g])%(long long)(pow(10,9)+7);
    30         }
    31         printf("%lld
    ",sum);
    32     }
    33     return 0;
    34 }

    D-小阳买水果

    链接:https://ac.nowcoder.com/acm/contest/949/D
    来源:牛客网

    题目描述

    水果店里有 n个水果排成一列。店长要求顾客只能买一段连续的水果。
    小阳对每个水果都有一个喜爱程度 ai,最终的满意度为他买到的水果的喜欢程度之和。
    如果和为正(不管是正多少,只要大于 0 即可),他就满意了。
    小阳想知道在他满意的条件下最多能买多少个水果。
    你能帮帮他吗?

    输入描述:

    第一行输入一个正整数 n,表示水果总数。
    第二行输入 n 个整数 ai,表示小阳对每个水果的喜爱程度。

    输出描述:

    一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)

    示例1

    输入

    5
    0 0 -7 -6 1

    输出

    1

    备注:

    1n2×106,|ai|103

    想法:i从1到n遍历时,就先求出1到i的和,然后在此sum后,只要有一个sum值比它大,就说明它俩中间的数的和为正数,此时的位置之差就是此刻连续的长度,跟max比较就好了

    但数据不允许,要对算法做优化。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define maxn 2000005
     5 using namespace std;
     6 int sum[maxn],maxx[maxn];
     7 int ans=0;
     8 int main()
     9 {
    10     int n;
    11     scanf("%d",&n);
    12     memset(maxx,-0x3f3f3f,sizeof(maxx));
    13     for(int i=1;i<=n;i++)
    14     {
    15         scanf("%d",&sum[i]);
    16         sum[i]+=sum[i-1];
    17     }
    18     for(int i=n;i>=1;i--)
    19     maxx[i]=max(sum[i],maxx[i+1]);
    20     for(int l=1,r=1;l<=n&&r<=n;l++,r++)
    21     {
    22         if(maxx[r]<=sum[l-1]) continue;
    23         else while(maxx[r]>sum[l-1]){
    24                     r++;
    25         }
    26         ans=max(ans,r-l);
    27      }
    28      printf("%d",ans);
    29  }
     1 #include<bits/stdc++.h>
     2 #define rep(X,A,B) for(int X=A;X<=B;X++)
     3 #define tep(X,A,B) for(int X=A;X>=B;X--)
     4 #define LL long long
     5 #define ls son[x][0]
     6 #define rs son[x][1]
     7 const int N=2000010;
     8 const int MOD=1e9+7;
     9 using namespace std;
    10  
    11 int n;
    12  
    13 struct nn{
    14     int num,pos;
    15 }a[N];
    16  
    17 int cmp(nn A,nn B){
    18     if(A.num==B.num)return A.pos>B.pos;
    19     return A.num<B.num;
    20 }
    21  
    22 int main(){
    23     scanf("%d",&n);
    24     int x;
    25     rep(i,1,n)scanf("%d",&x),a[i].num=a[i-1].num+x,a[i].pos=i;
    26     n++;a[n].pos=a[n].num=0;
    27     sort(a+1,a+n+1,cmp);
    28     int las=n,ans=0;
    29     rep(i,1,n){
    30         las=min(las,a[i].pos);
    31         if(las<a[i].pos)ans=max(ans,a[i].pos-las);
    32     }
    33     printf("%d
    ",ans);
    34     return 0;
    35 }

    题解地址

  • 相关阅读:
    Java基础——原码, 反码, 补码 详解
    为什么Java byte 类型的取值范围是-128~127
    JAVA 各种数值类型最大值和最小值 Int, short, char, long, float,&nbs
    JDK config
    为什么要设置Java环境变量(详解)
    什么是JAR包?
    如何用python将一个时间序列转化成有监督学习
    ImportError: numpy.core.multiarray failed to import
    搭建SDN网络——mininet
    回溯法解决最大团问题
  • 原文地址:https://www.cnblogs.com/jiamian/p/11179585.html
Copyright © 2011-2022 走看看