zoukankan      html  css  js  c++  java
  • 2019年2月17日训练日记

    今天写几个题目:

    过河
    (对规律的把握)
    有 n 个人来到了一条河的一边,他们都想到河的另一边。河的宽度为 k 米。不幸
    的是,河边只有一条船(在他们所在的一边),容量为 m 人。他们要划船过河,
    使所有人都到河的另一边。假设所有人都会划船,请问船最少经过的路程是多少
    米,才能使所有人到达河的另一边?
    数据范围:
    1<=n<=1e9,2<=m<=1e9,1<=k<=1e9
    输入
    三个数,n,m,k,含义如上所述,每个数之间以一个空格隔开。
    输出
    船经过的最少路程,使所有人都到河的另一边。
    样例
    input

    1 2 3
    

    output

    3
    

    例程:
    首先,注意到如果 n<=m,只需要一次即可将所有人运到河的对岸,那么船的路程
    显然为 k。否则,第一次运输之后,必须留下至少一个人再将船划回对岸。也就是
    说,除了第一次划船可以运送 m 个人到对岸以外,剩下的每一次运输(一个来
    回)都只能运送 m-1 人到达对岸(第一次的第 m 个人划船,因为最终他是到达对
    岸的)。也可以想象成每次运 m-1 人,当未到达对岸的人加上划船的人<=m 人,
    就可以一次运过去了。注意船的来回之间的路程需要*2。然后就是注意精度会爆
    int,需要用 long long。
    这种做法效率很高,时间复杂度为 O(1)。有的同学运用了复杂的过程模拟,也可
    以满分通过本题,不过效率较低。

     #include<bits/stdc++.h>
     #define ll long long
     using namespace std;
     int main()
     {
     int n,m,k,ans;
     scanf("%d%d%d",&n,&m,&k);
     if(n<=m) printf("%d
    ",k);
     else {
     n-=m;
     ans=((n-1)/(m-1)+1);
     ans=ans*2+1;
     printf("%lld
    ",(ll)ans*k);
     }
     }
    

    准时的外卖?五星好评!
    (对时间差的计算)
    众所周知,ACM 集训队是一个外卖集训队,在这里你可以订各种各样的外卖,订外卖之余也可以抽时间打一下 ACM 比赛啥的,非常的惬意…… 而作为集训队最爱订外卖和最有原则的 LSD 学长,对于外卖的评价非常的偏执,不论味道和价格,他给外卖评分的准则就是是否能按时送到,如果在下单 1 小时 17 分钟以内(包括 1 小时 17 分钟时)送到,那么 LSD 学长就会给出五星好评,否则,晚一分钟,他便会减少一颗星,直到一星为止。
    最近你知道了这两天 LSD 学长订外卖的时间和送到的时间,你能靠这些数据算出 LSD 学长每天打出
    的评分吗?
    输入:
    第一行一个 D(1<=D<=100),代表 LSD 学长最近 D 天订外卖的情况;
    以下有 D 组数据,每组两行,分别代表了下单时间 t1 与送到时间 t2;
    时间采用 24 小时制,用 HH:MM 表示,HH 代表小时,MM 代表分钟,如果数字小于 10 则用前导
    零填充(比如六点三分表示为 06:03)。
    保证送到时间不小于下单时间,保证送到时间与下单时间是同一天内。
    输出:
    每组数据输出一行,每行有几个“*”(不加引号),代表 LSD 学长对于这次外卖给出了几星评价(每行
    输出结尾没有多余空格)。
    样例输入:

    5
    09:00
    10:16
    09:00
    10:17
    09:00
    10:18
    09:00
    10:19
    09:00
    10:50
    

    样例输出:

    *****
    *****
    ****
    ***
    

    *小提示:
    第一天外卖 9 点整下单,10 点 16 送到,共花费 1 小时 16 分钟,学长打出了”*****”;

    第三天外卖 9 点整下单,10 点 18 送到,共花费 1 小时 18 分钟,学长打出了”****”;

    第五天外卖 9 点整下单,10 点 50 送到,共花费 1 小时 50 分钟,学长打出了”*”;
    字符”0”的 ascii 码是 48,将字符型的变量赋值给整数型的变量会传递 ascii 码的数值
    题解:
    这道题没有什么思维性,只需要读懂题意,按照题目要求写代码即可,主要考察代码能力,具体的实现方法见第三页代码。
    标程:

    #include <bits/stdc++.h>
    using namespace std;
    char t1[10],t2[10]; //定义两个字符串来存储时间
    int main()
    {
    int D;
    cin>>D;
    while(D--)
    {
    for(int i=0;i<5;i++)
    {
    cin>>t1[i];
    t1[i]-='0';
    }
    for(int i=0;i<5;i++)
    {
    cin>>t2[i];
    t2[i]-='0';
    }
    /*以上都是输入,也可以使用 scanf(“%d:%d”,&a,&b)来进行输入*/
    int time1,time2,time3;
    time1=(t1[0]*10+t1[1])*60+(t1[3]*10+t1[4]);
    time2=(t2[0]*10+t2[1])*60+(t2[3]*10+t2[4]);
    time3=time2-time1;//计算时间差
    if(time3<=77)
    {
    cout<<"*****"<<endl;//此情况五星
    }
    else //这里用多次的分支语句判断亦可以
    {
    int n;
    n=5-(time3-77);
    cout<<"*";
    for(int i=0;i<n-1;i++)
    {
    cout<<"*";//根据时间打星,记得最少一颗星!
    }
    cout<<endl;
    }
    }
    }
    

    简单的数学题 解题报告
    这是一道简单的数学题。给你一个数 n,求
    在这里插入图片描述

    数据范围:1<=n<=1000000
    注意:本题的时限只有 2ms!!!
    tips:
    在这里插入图片描述
    输入
    一个数 n
    输出
    如上所述
    样例
    input

    1
    

    output

    1
    

    例程:
    80 分的做法:
    由于 C/C++中整数除法默认的就是向下取整,所以直接 for 累加一遍 n/i 的和就
    行。但是此解法效率较低,复杂度为 O(n)。
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    long long n,m,k,ans;
    int main()
    {
    ans=0;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    ans+=n/i;
     printf("%lld
    ",ans);
     }
    

    100 分的做法:
    除法有一个性质,就是对于每个 n,每个 i(1<=i<=n),值为 n/i(向下取整)的有
    (n/(n/i))-i+1(都是向下取整)个。所以一次可以跳(n/(n/i))-i+1 个。称此方法为
    除法分块,效率要比上面高很多,复杂度为 O(sqrt(n))。
    代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main()
    {
    ll n,k,s,ans=0;
    scanf("%lld",&n);
    for(ll i=1;i<=n;i=s+1)
    {
     k=n/i; 
     s=n/k; 
     ans+=(s-i+1)*k; 
     } 
     printf("%lld
    ",ans); 
     }
    

    这道题是暴力
    给定一个整数序列,求此整数序列中最大连续子序列和(子序列长度可以为0)
    例如:
    给定 Arr = {-1, 2, 3, -4, 5, -6} ,则此序列的最大连续子序列和为: 6 ,即: {2, 3, -4, 5}
    输入
    第一行为一个整数 n,表示此序列中的元素个数后面 n 行为序列中的元素
    n 的数据范围:90%, (0, 100]
    10%, [1e5,1e5]
    每个元素: [-100, 100]
    输出
    输出最大连续子序列和
    样例
    input

    6
    -1
    2
    3
    -4
    5
    -6
    

    output

    6
    

    例程:
    90%的数据:(利用两个for循环枚举其子序列即可)
    此题若使用暴力,可得90分,
    暴力的时间复杂度达到了O(n^2),对于最后一个1e5的数据,即到达了1e10的规模,会导致超时(1e9就有可能超时)
    100%数据:(dp,最大连续子段和,经典dp,自行百度即可-

    #include <iostream>
    using namespace std;
    int main()
    {
    int n = 0;
    cin>>n;
    int sum = 0, res = 0;
    for(int i = 0; i<n; i++)
    {
    int tmp;
    cin>>tmp;
    if(sum < 0)
    {
    sum = 0;
    }
    sum += tmp;
    if(sum > res)
    {
    res = sum;
    }
    }
    cout << (res < 0 ? 0 : res) << endl;
    return 0;
    }
    
  • 相关阅读:
    VOA 2009/11/02 DEVELOPMENT REPORT In Kenya, a Better Life Through Mobile Money
    2009.11.26教育报道在美留学生数量创历史新高
    Java中如何实现Tree的数据结构算法
    The Python Tutorial
    VOA HEALTH REPORT Debate Over New Guidelines for Breast Cancer Screening
    VOA ECONOMICS REPORT Nearly Half of US Jobs Now Held by Women
    VOA ECONOMICS REPORT Junior Achievement Marks 90 Years of Business Education
    VOA 2009/11/07 IN THE NEWS A Second Term for Karzai; US Jobless Rate at 10.2%
    Ant入门
    Python 与系统管理
  • 原文地址:https://www.cnblogs.com/study-hard-forever/p/12130052.html
Copyright © 2011-2022 走看看