蓝桥杯刷题七

  1. 归并排序

模板

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],temp[N];
void msort(int l,int r)
{
    if(l>=r) return ;
    int mid=l+r>>1;
    msort(l,mid);
    msort(mid+1,r);
    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r)
        if(a[i]<=a[j])
            temp[k++]=a[i++];
        else temp[k++]=a[j++];
    while(i<=mid)
        temp[k++]=a[i++];
    while(j<=r)
        temp[k++]=a[j++];
    for(int i=l,j=0;i<=r;) a[i++]=temp[j++];
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    msort(0,n-1);
    for(int i=0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}

2.移动距离

公式很容易推的

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int cnt1,cnt2;
    int w,a,b;
    cin>>w>>a>>b;
    int res=abs((w+a-1)/w-(w+b-1)/w);
    if(((w+a-1)/w)%2==1)
    {
        cnt1=a%w;
        if(cnt1==0)
            cnt1=w;
    }
    else if(((w+a-1)/w)%2==0)
    {
        cnt1=w-a%w+1;
        if(cnt1==w+1)
            cnt1=1;
    }
    if(((w+b-1)/w)%2==1)
    {
        cnt2=b%w;
        if(cnt2==0)
            cnt2=w;
    }
    else if(((w+b-1)/w)%2==0)
    {
        cnt2=w-b%w+1;
        if(cnt2==w+1)
            cnt2=1;
    }
    cout<<res+abs(cnt1-cnt2)<<endl;
    return 0;
}

3.日期问题

注意想一种比较好的思路 并且注意一下一个知识点 格式化输入补前导零printf("%0xd",a);

这个就是如果a不够x位 就在前面补前导零

#include <cstdio>
#include <iostream>

using namespace std;

int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool check_valid(int year, int month, int day)
{
    if (month == 0 || month > 12) return false;
    if (day == 0) return false;
    if (month != 2)
    {
        if (day > days[month]) return false;
    }
    else
    {
        int leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
        if (day > days[month] + leap) return false;
    }

    return true;
}

int main()
{
    int a, b, c;
    scanf("%d/%d/%d", &a, &b, &c);

    for (int date = 19600101; date <= 20591231; date ++ )
    {
        int year = date / 10000, month = date % 10000 / 100, day = date % 100;
        if (check_valid(year, month, day))
        {
            if ((year % 100 == a && month == b && day == c) ||  // 年/月/日
                (month == a && day == b && year % 100 == c) ||  // 月/日/年
                (day == a && month == b && year % 100 == c) )   //月/日/年
                printf("%d-%02d-%02d\n", year, month, day);  //补前导0
        }
    }

    return 0;
}

4.航班时间

去乘起飞时间+航行时间+时差=去乘降落时间 (公式一)

回程起飞时间+航行时间-时差=回程降落时间 (公式二)

求:航行时间

已知:去乘起飞时间,回程起飞时间,去乘降落时间,回程降落时间

根据公式一+公式二:

去乘起飞时间+回程起飞时间+2*航行时间=去乘降落时间+回程降落时间

航行时间=(去乘降落时间-去乘起飞时间+回程降落时间-回程起飞时间)/2

用scanf格式化输入 很舒服就能做对了

#include<bits/stdc++.h>
using namespace std;
int getTime(void)
{
    int h1,m1,s1,h2,m2,s2,d=0;
    scanf("%d:%d:%d %d:%d:%d (+%d)",&h1,&m1,&s1,&h2,&m2,&s2,&d);
    int time=d*24*3600+h2*3600+m2*60+s2-(h1*3600+m1*60+s1);
    return time;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int i = 0; i < t; i++)
    {
        int time1=getTime();
        int time2=getTime();
        int t=(time1+time2)/2;
        printf("%02d:%02d:%02d\n", t/3600, t/60%60, t%60);
    }
    return 0;
}

5.外卖店优先级

按id为第一关键字排序 先判断一个店能不能ans++,再判断第二个 第三个.....

然后注意一点细节就好了

cur初始化的时候 观察循环是从1到m的 所以m[0]的订单是没有加上的 所以cur初始化为2是加上m[0] 然后后面的每一步都是加上集合中的第一个 所有一直初始化为2

然后diff是有边界有特殊情况的

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct message
{
    int t, id;
    bool operator < (const message& m)
    {
        return id < m.id || id == m.id && t < m.t;
    }
}a[N];
int main()
{
    int ans=0;
    int n,m,t;
    cin>>n>>m>>t;
    for(int i=0;i<m;i++)
        cin>>a[i].t>>a[i].id;
    sort(a,a+m);
    int cur=2;
    bool st=false;
    for(int i=1;i<=m;i++)
    {
        if(a[i].id!=a[i-1].id)
        {
            if(st&&cur-(t-a[i-1].t)>3) ans++;
            st=false;
            cur=2;
        }
        else
        {
            int diff=a[i].t-a[i-1].t-1;
            if(diff==-1) diff=0;
            cur=max(0,cur-diff);
            if(cur<=3) st=false;
            cur+=2;
            if(cur>5) st=true;
        }
    }
    cout<<ans<<endl;
    return 0;
}

6.逆序对数量

归并排序可以直接算的 cnt+=mid-i+1;理解归并排序原理就知道为什么了

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],temp[N];
int cnt;
void msort(int l,int r)
{
    if(l>=r) return ;
    int mid=l+r>>1;
    msort(l,mid);
    msort(mid+1,r);
    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r)
        if(a[i]<=a[j])
            temp[k++]=a[i++];
        else 
        {
            cnt+=mid-i+1;
            temp[k++]=a[j++];
        }
    while(i<=mid)
        temp[k++]=a[i++];
    while(j<=r)
        temp[k++]=a[j++];
    for(int i=l,j=0;i<=r;) a[i++]=temp[j++];
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    msort(0,n-1);
    for(int i=0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值