zoukankan      html  css  js  c++  java
  • 牛客网NOIP赛前集训营-普及组

     第一场:

    A-绩点

    题目描述

    小A刚考完大学考试。现在已经出了n门课的成绩,他想自己先算一下这些课的绩点是多少。设第i门课的他拿到的绩点是gpai,而这门课的学分是sci,那么他的总绩点用下面的公式计算:
    ,
    换言之,设S为sci的和,T为gpai与sci的乘积的和。那么小A的绩点就是T除以S的值。

    输入描述:

    第一行一个整数n。
    接下来n行,每行两个数gpai和sci。

    输出描述:

    输出一行一个实数,表示小A的绩点。输出四舍五入保留1位小数。
    示例1

    输入

    3
    3.7 2
    4.0 2
    3.7 5

    输出

    3.8

    备注:

    总共有5个数据点:
    第1个数据点,满足所有学科得到的gpa都相同。
    第2个数据点,满足n=3。
    第3个数据点,满足所有学科的sc值都相同。
    对于所有数据点,都满足n<=50, gpai等于3.3, 3.7或4.0。sci为不超过5,不小于1的整数。
    解题思路:简单套公式即可。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     int n;double gpa,sc,m1,m2;
     5     while(cin>>n){
     6         m1=m2=0;
     7         while(n--){
     8             cin>>gpa>>sc;
     9             m1+=gpa*sc;
    10             m2+=sc;
    11         }
    12         printf("%.1f
    ",m1/m2);
    13     }
    14     return 0;
    15 }

    B-巨大的棋盘

    题目描述

    小A站在一个巨大的棋盘上。这个棋盘可以看成是一个网格图。这个网格图的大小为n*m。左上角坐标为(1,1),右下角坐标为(n,m)。这个棋盘很特别,他每行每列都是一个环。具体来说,当小A站在第一行,他往上走的时候,他会走到第n行,站在第n行往下走会走到第一行。对于第一列和第m列类似。小A在棋盘上可以上下左右走,假设他站在位置(i,j),向上走,会走到(i-1,j),向下回到(i+1,j),向左到(i,j-1),向右到(i,j+1)。注意由于棋盘是循环的,他不会走出这个棋盘。
    现在小A有一个固定的行走序列S,代表他每一步走的方向,U代表向上,D代表向下,L代表向左,R代表向右。比如小A一开始在(1,1),棋盘大小为3*4。行走序列为UULRD。那么他会依次经过(3,1),(2,1),(2,4),(2,1),(3,1)。但小A觉得只走一遍S太无聊,因此他会重复走这个序列T次。比如上面的例子,当T=2时,真正的行走序列为UULRDUULRD。
    小A有q个备选的起点位置。他一开始先给定你棋盘大小与行走序列,对于每个起点位置,他想知道,他沿着序列走,最终会走到哪个位置停下。

    输入描述:

    第一行三个整数n,m,T。
    接下来一行一个字符串S,代表行走序列。注意行走序列在真实走的时候要重复T次。
    接下来一个整数q。
    接下来q行,每行两个整数x,y,代表小A的一个备选起点。

    输出描述:

    输出q行,每行两个整数,输出对于这个起点,最后的终点是哪里。
    示例1

    输入

    3 6 4
    DUUUDLLLLR
    3
    3 2
    2 5
    1 4
    

    输出

    2 2
    1 5
    3 4
    

    备注:

    20%: |S| * T <= 10^6, q = 1
    40%: |S| * T <= 10^6, q <= 10^5
    60%: |S|, T <= 10^5, q <= 10^5
    100%: 1 <= T,n,m <= 10^9, 1 <= x <= n, 1 <= y <= m. 1<= q, |S| <= 10^5
    其中|S|代表S的长度。
    解题思路:简单模拟一下即可推出答案!!!
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+5;char str[maxn];
     4 int main(){
     5     long long n,m,t,q,x,y,_x,_y;
     6     while(cin>>n>>m>>t){
     7         cin>>str>>q;_x=_y=0;
     8         for(int i=0;str[i]!='';++i){
     9             if(str[i]=='D')_x++;
    10             else if(str[i]=='U')_x--;
    11             else if(str[i]=='L')_y--;
    12             else _y++;
    13         }
    14         _x*=t,_y*=t;
    15         while(q--){
    16             cin>>x>>y;
    17             x+=_x,y+=_y;
    18             x%=n,y%=m;
    19             while(x<=0)x+=n;
    20             while(y<=0)y+=m;
    21             cout<<x<<' '<<y<<endl;
    22         }
    23     }
    24     return 0;
    25 }

    第二场:

    A-你好诶加币

    题目描述

    牛牛刚学习了输入输出,他遇到了一道这样的题目。
    输入2个整数a和b
    保证输入的a和b在long long范围之内,即满足
    -9223372036854775808 <= a, b <= 9223372036854775807
    计算a+b的值,即这两个数字的和。
    如果a+b在long long范围之内,即满足
    -9223372036854775808 <= a + b <= 9223372036854775807
    那么输出一行一个整数表示a+b的结果。
    如果a+b不在long long范围之内,即越界了,那么输出"hello, %lld ",包含引号。
    具体可以参见样例。

    输入描述:

    输入只有一行,包含用空格分开的两个整数,表示a和b。

    输出描述:

    如果a+b在long long范围之内,输出一行一个整数,表示a+b的结果;否则输出"hello, %lld
    ",包含引号。
    示例1

    输入

    -9223372036854775808 9223372036854775807

    输出

    -1
    示例2

    输入

    9223372036854775807 1

    输出

    "hello, %lld
    "

    备注:

    正确计算a+b可以得到50分
    正确输出"hello, %lld "也可以得到50分
    解题思路:java大数简单判断或者C++也可以判断溢出的情况。
    AC之java代码:
     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 public class Main {
     4     public static void main(String[] args) {
     5         Scanner scan = new Scanner(System.in);
     6         BigInteger c = new BigInteger("9223372036854775807");
     7         BigInteger d = new BigInteger("-9223372036854775808");
     8         while(scan.hasNext()){
     9             BigInteger a = scan.nextBigInteger();
    10             BigInteger b = scan.nextBigInteger();
    11             a = a.add(b);
    12             if(a.compareTo(d)==-1||a.compareTo(c)==1)
    13                 System.out.println(""hello, %lld\n"");
    14             else System.out.println(a);   
    15         }               
    16     }
    17 }

    AC之C++代码:溢出的两种情况:①a>0,b>0,a+b<0(正向最多加到-2即小于0);②a<0,b<0,a+b>=0;(反向最多减到0)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;LL a,b;
     4 int main(){
     5     while(cin>>a>>b){
     6         if((a>0&&b>0&&a+b<0)||(a<0&&b<0&&a+b>=0))cout<<""hello, %lld\n""<<endl;
     7         else cout<<(a+b)<<endl;
     8     }
     9     return 0;
    10 }

    B-最后一次

    题目描述

    牛牛最近学习了质数的概念。
    质数指在大于1的自然数中,除了1和它本身以外不再有其他因数。
    输入一个n,输出小于等于n最大的质数。

    输入描述:

    输入一个整数n

    输出描述:

    输出小于等于n的最大的质数
    示例1

    输入

    2

    输出

    2
    示例2

    输入

    100

    输出

    97

    备注:

    对于所有数据: 2 <= n <= 1000000000000
    30分: n <= 100000
    70分: n <= 1000000000
    解题思路:找不大于n的最近一个素数,简单暴力一下即可。
    AC代码:
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<string.h>
     5 using namespace std;
     6 typedef long long LL;LL n;
     7 bool is_prime(LL n){
     8     for(LL i=2;i*i<=n;++i)
     9         if(n%i==0)return false;
    10     return true;
    11 }
    12 int main(){
    13     while(~scanf("%lld",&n)){
    14         for(LL i=n;i>1;--i)
    15             if(is_prime(i)){printf("%lld
    ",i);break;}
    16     }
    17     return 0;
    18 }

    第三场:

    A-十七边形

    题目描述

    牛牛想在一个半径为r的圆中,找到一个内接的十七边形,使他的面积最大。
    输入半径r,输出最大的面积。
    1 <= r <= 10000
    在10组数据中,存在5组数据,半径为1,10,100,1000,10000。
    换句话说,对于50%的数据,r是10的次幂。

    输入描述:

    输入一行一个整数,表示半径r。

    输出描述:

    输出一行一个实数,表示最大的内接十七边形的面积。
    四舍五入保留6位小数。
    示例1

    输入

    10000
    

    输出

    307055416.259080
    解题思路:圆内接十七边形得到其最大面积必定为正十七边形的面积,简单套个公式即可。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const double pi=acos(-1.0);
     4 int main(){
     5     double r;
     6     while(~scanf("%lf",&r)){
     7        printf("%.6f
    ",0.5*sin(2*pi/17.0)*r*r*17);
     8     }
     9     return 0;
    10 }

    第四场:

    A.新个税

    题目描述

    牛牛已知每月的税前收入,他想知道在新个税下,税收后收入是多少?
    个税计算方法是这样的:
    综合所得金额 - 新起征点5000元 = 应纳税所得额
    其中 综合所得金额 就是税前收入,(你可以忽略五险一金,专项扣除等我没有提到的东西)
    对于 应纳税所得额
    1. 不超过3000元的部分,税率3%
    2. 超过3000元至12000元的部分,税率10%
    3. 超过12000元至25000元的部分,税率20%
    4. 超过25000元至35000元的部分,税率25%
    5. 超过35000元至55000元的部分,税率30%
    6. 超过55000元至80000元的部分,税率35%
    7. 超过80000元的部分,税率45%
    税前收入 - 个人所得税 = 税后收入
    为了方便计算,保证收入是100的倍数,因此输出一定是整数。
    虽然个人所得税法没有写明,但是我相信对于税前收入5000以下的人,是可以不交个人所得税的,当然也不会受到国家的补助。(税不会是负数)
    存在7组数据为5000, 8000, 17000, 30000, 40000, 60000, 85000
    输入保证 2400 <= 税前收入 <= 240000

    输入描述:

    输入一行一个整数表示税前收入

    输出描述:

    输出一行一个整数表示税后收入
    示例1

    输入

    20000

    输出

    18410

    说明

    应纳税所得额为15000,其中
    有3000落在第一部分,有9000落在第二部分,有3000落在第三部分。
    个人所得税 = 3000 * 3% + 9000 * 10% + 3000 * 20% = 90 + 900 + 600 = 1590
    所以税后收入是18410。
    解题思路:水过!
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int main(){
     5     int n,m,tot;
     6     while(cin>>n){
     7         if(n<=5000)cout<<n<<endl;//不用缴税
     8         else{
     9             m=n-5000;tot=m;
    10             if(m<=3000)tot-=m/100*3;
    11             else if(m<=12000)tot-=90+(m/10-300);
    12             else if(m<=25000)tot-=990+(m/10-1200)*2;
    13             else if(m<=35000)tot-=3590+(m/100-250)*25;
    14             else if(m<=55000)tot-=6090+(m/10-3500)*3;
    15             else if(m<=80000)tot-=12090+(m/100-550)*35;
    16             else tot-=20840+(m/100-800)*45;
    17             cout<<tot+5000<<endl;
    18         }
    19     }
    20     return 0;
    21 }

    B.二分之一

    题目描述

    输入n,牛牛想知道0.5的n次方的精确值。
    注意是精确值,也就是小数有多少位,就要输出多少位,不四舍五入。(当然也不输出多余的0)
    对于100%的数据,1 <= n <= 1000
    对于60%的数据,1 <= n <= 27
    对于30%的数据,1 <= n <= 4

    输入描述:

    输入一行一个整数n。

    输出描述:

    输出0.5的n次方的精确值。
    示例1

    输入

    2

    输出

    0.25
    示例2

    输入

    77

    输出

    0.00000000000000000000000661744490042422139897126953655970282852649688720703125

    说明

    精确值
    解题思路:java水过!
    AC代码:
     1 import java.math.BigDecimal;
     2 import java.util.Scanner;
     3 public class Main {
     4     public static void main(String[] args) {
     5         Scanner scan = new Scanner(System.in);
     6         BigDecimal bd = new BigDecimal("0.5");
     7         while(scan.hasNext()){
     8             BigDecimal result = bd.pow(scan.nextInt());
     9             //stripTrailingZeros()的使用方法:返回数值上等于此小数,但从该表示形式移除所有尾部零的 BigDecimal。
    10             //toPlainString()的使用方法:返回不带指数字段的此 BigDecimal的字符串表示形式。
    11             String obj = result.stripTrailingZeros().toPlainString();
    12             System.out.println(obj);
    13         }
    14     }
    15 }

     第五场:

    A.体积数

    题目描述

    众所周知,在二维平面上,边长为 a 的正方形面积为 a2;在三维空间中,边长为 a 的立方体的体积为 a3;在 d 维空间中,边长为 a 的立方体的体积为 ad
    可怜把所有能被表示成 ad(其中 a,d 都是正整数,d ≥ 2)的正整数定义为体积数。举例来说,小于等于 10 的体积数有 4 个,分别为 1,4,8,9。
    现在可怜想让你计算小于等于 n 的体积数有多少个。

    输入描述:

    输入一行一个整数 n。
    对于30%的数据,n ≤ 100。对于60%的数据,n ≤ 10^5。
    对于100%的数据,1 ≤ n ≤ 10^7。

    输出描述:

    输出一行一个整数表示答案。
    示例1

    输入

    10
    

    输出

    4
    

    说明

    小于等于 10 的体积数有 1,4,8,9。
    示例2

    输入

    100

    输出

    13

    说明

    小于等于 100 的体积数有 1,4,8,9,16,25,27,32,36,49,64,81,100。
    解题思路:简单暴力+前缀和即可。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL maxn=1e7+5;
     5 int n,cnt[maxn],ans[maxn];
     6 int main(){
     7     memset(cnt,0,sizeof(cnt));cnt[1]=1;
     8     for(LL i=2;i*i<maxn;++i)
     9         for(LL j=i*i;j<maxn;j*=i)
    10             cnt[j]=1;
    11     for(LL i=1;i<maxn;++i)ans[i]=ans[i-1]+cnt[i];
    12     while(cin>>n){cout<<ans[n]<<endl;}
    13     return 0;
    14 }

     第六场:

    A.金币

    题目描述

    国王将金币作为工资,发放给忠诚的骑士。
    第1天,骑士收到1枚金币;之后4天(第2,3,4,5天),每天收到2枚金币;之后9天(第6-14天),每天收到3枚金币;之后16天(第15-30天),每天收到4枚金币……;这种工资发放模式会一直这样延续下去:当连续N^2天每天收到N枚金币后,骑士会在之后的连续(N+1)^2天里,每天收到N+1枚金币。
    请计算在第l到r天里,骑士一共获得了多少金币。

    输入描述:

    一行两个整数l,r

    输出描述:

    一行表示答案
    示例1

    输入

    4 6

    输出

    7

    说明

    2+2+3=7

    备注:

    全部的输入数据满足:1 ≤ l ≤ r ≤ 10^10。
    共10个测试点。对于第i(i=1..10)个测试点,r<=10^i。
    解题思路:求前n项的平方和,公式为1+2+...+n=n(n+1)(2n+1)/6,然后简单做个查找即可。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 LL l,r,answer;vector<LL> vec;
     5 int main(){
     6     vec.clear();
     7     for(LL i=1;i<4000;++i)
     8         vec.push_back(i*(i+1)/2*(2*i+1)/3);
     9     /*for(LL i=0;i<5;++i)
    10         cout<<i<<' '<<vec[i]<<endl;*/
    11     while(cin>>l>>r){
    12         LL pos1=lower_bound(vec.begin(),vec.end(),l)-vec.begin();
    13         LL pos2=lower_bound(vec.begin(),vec.end(),r)-vec.begin();
    14         //cout<<pos1<<' '<<pos2<<endl;
    15         if(pos1==pos2)answer=(r-l+1)*(pos1+1);
    16         else {
    17             answer=(vec[pos1]-l+1)*(pos1+1)+(r-vec[pos2-1])*(pos2+1);
    18             for(LL i=pos1+1;i<=pos2-1;++i)answer+=(i+1)*(vec[i]-vec[i-1]);
    19         }
    20         cout<<answer<<endl;
    21     }
    22     return 0;
    23 }

     第七场:

    A.循环

    题目描述

    牛牛正在学习See语言程序设计,今天他学到了循环语句。
    See语言中的循环语句和C/C++风格类似,为以下格式:
    for (i = a; i op b; i += c);
    在上述语句中,a b c是整数,op是关系运算符,可能是 <=, >=或者 !=,分别代表小于等于,大于等于、不等于。
    循环的执行过程和C语言类似:
    1、首先执行赋值语句i = a
    2、计算布尔表达式i op b的值,如果为假跳到步骤4,否则继续步骤3
    3、执行赋值语句i += c, 既i = i + c,然后跳到步骤2
    4、循环结束
    需要注意的是,循环变量i的类型是See语言中的整型数,它的取值范围可以很大,不会像C语言中的int一样存在溢出
    牛牛希望计算出步骤3(i += c)会执行多少次

    输入描述:

    输入仅一行四个整数a, op, b, c
    其中op = 1代表<=, op = 2代表>=, op = 3代表!=
    对于50%的数据,0 <= a, b, c <= 100
    对于100%的数据, -10<= a, b, c <= 109

    输出描述:

    输出一行一个整数代表步骤3执行的次数,如果循环永远不会终止(死循环)则输出-1
    示例1

    输入

    0 1 100 2

    输出

    51

    说明

    语句为for (i = 0; i <= 100; i += 2);
    示例2

    输入

    0 3 100 3

    输出

    -1

    说明

    语句为for (i = 0; i != 100; i += 3), 循环永远不会结束。
    解题思路:题目很简单,分情况讨论即可。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 LL a,op,b,c,answer;
     5 int main(){
     6     while(cin>>a>>op>>b>>c){
     7         if(op==1){
     8             if(a<=b){
     9                 if(c>0)answer=(b-a)/c+1;
    10                 else answer=-1;
    11             }else answer=0;
    12         }
    13         else if(op==2){
    14             if(a>=b){
    15                 if(c<0)answer=(b-a)/c+1;
    16                 else answer=-1;
    17             }else answer=0;
    18         }
    19         else{
    20             if(a<b){
    21                 if(c>0)answer=((b-a)%c)?-1:((b-a)/c);
    22                 else answer=-1;
    23             }else if(a==b)answer=0;
    24             else{
    25                 if(c<0)answer=((b-a)%c)?-1:((b-a)/c);
    26                 else answer=-1;
    27             }
    28         }
    29         cout<<answer<<endl;
    30     }
    31     return 0;
    32 }

    B.供给和需求

    题目描述

    牛牛正在学习经济学中的价格理论:价格是由供给和需求决定的
    假设在一个市场中,一共有N个买家和M个商家。商家是商品的供应方,买家是商品的需求方。
    对于每一个买家有两个参数a和b:当价格为0时,这个买家的需求量为a,每当价格提高1时,需求量会减少b。(当然,需求量不可能是负数,因此最多降为0)
    对于每一个商家有一个参数c:当价格为0时,供给量为0(因为贩卖物品得不到收益,商家就不会制造物品),每当价格提高1时,供给量会增加c
    市场上的总需求量等于每一个买家的需求量之和,总供给量等于每一个商家的供给量之和。
    市场会起到调节价格的作用(具体来说,当供给大于需求时,价格下降,当供不应求时,价格上升),最终使得供给和需求相等。
    本题中规定价格一定是一个整数,使得供给量和需求量差的绝对值最小,牛牛希望你帮忙计算出绝对值最小是多少。

    输入描述:

    输入第一行N,M行描述买家的数量和商家的数量
    接下来N行描述N个买家,第i行有两个参数a_i和b_i描述第i个买家
    接下来M行描述M个商家,第i行有一个参数c_i描述第i个商家
    对于40%的数据, 1 <= N, M, ai, bi, ci <= 100
    对于100%的数据, 1 <= N, M, a <= 100000, 1 <= bi, ci <= 100

    输出描述:

    输出一行一个整数代表供给量和需求量差的绝对值最小可能是多少。
    示例1

    输入

    2 2
    10 1
    20 2
    2
    1

    输出

    0
    解题思路:典型的二分查找,通过查找价格来使供需逐渐达到平衡,同时更新供给量和需求量之差的绝对值的最小值。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn=1e5+5;
     5 LL n,m,ans,l,r,mid,a[maxn],b[maxn],c[maxn];
     6 bool check(LL x){
     7     LL t1=0,t2=0;
     8     for(LL i=0;i<m;++i)t1+=x*c[i];//
     9     for(LL i=0;i<n;++i)t2+=max(0LL,a[i]-x*b[i]);//
    10     ans=min(ans,abs(t1-t2));
    11     return t1>t2;
    12 }
    13 int main(){
    14     while(cin>>n>>m){
    15         for(LL i=0;i<n;++i)cin>>a[i]>>b[i];
    16         for(LL i=0;i<m;++i)cin>>c[i];
    17         ans=LONG_LONG_MAX;l=1,r=100000;//区间[1,100000]二分找价格x
    18         while(l<=r){
    19             mid=(l+r)>>1;
    20             if(check(mid))r=mid-1;//供大于求,x太大-->左边找
    21             else l=mid+1;//供不应求,x太小-->右边找
    22         }
    23         cout<<ans<<endl;
    24     }
    25     return 0;
    26 }
  • 相关阅读:
    整数转字符串
    SharePoint介绍性文章
    Disable Sharepoint 2007 show as System Account when system admin login
    通过IP地址获得主机名
    从文本文件读取信息
    数据库连接池问题[转]
    企业类库问题 public key 问题[经过自己测试]
    Google Analytics异步代码创建虚拟浏览量跟踪
    同一主机上WordPress博客更换域名简易八步骤(2)
    关于application/xwwwformurlencoded等字符编码的解释说明
  • 原文地址:https://www.cnblogs.com/acgoto/p/9653118.html
Copyright © 2011-2022 走看看