刷题集合5

文章讲述了在一个矩阵排列的小区中,给定两个楼号,如何计算它们之间的最短移动距离;同时介绍了如何处理不同时区的航班起降时间,计算实际飞行时间以及外卖店优先级的动态变化。
摘要由CSDN通过智能技术生成

 移动距离

题目描述
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
其楼房的编号为1,2,3… 当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为6时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 …
我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离
(不能斜线方向移动)
输入
输入存在多组测试数据
输入为3个整数w m n,空格分开,都在1到10000范围内
w为排号宽度,m,n为待计算的楼号。
输出
要求输出一个整数,表示m n 两楼间最短移动距离。
样例输入 Copy
6 8 2
4 7 20
样例输出 Copy
4
5

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    int w,m,n;
    cin>>w>>m>>n;
    m--,n--;
    int x1=m/w,x2=n/w;
    int y1=m%w,y2=n%w;
    if(x1%2){y1=w-1-y1;}
    if(x2%2){y2=w-1-y2;}
    cout<<abs(x1-x2)+abs(y1-y2);
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int i,j,w;
int d(int x,int y){
    int a;
    if(y%2==0){
        a=x%w;
        if(a==0){
            a=w;
        }
    }else{
         a=w-x%w+1;
         if(a==w+1){
             a=1;
         }
    }
    return a;
}
int main(){
    int  m,n,dis=0;
    cin>>w>>m>>n;
     i=m/w,j=n/w;
     if(m%w==0)i--;
     if(n%w==0)j--;
    dis+=max(i,j)-min(i,j);
    dis+=max(d(m,i),d(n,j))-min(d(m,i),d(n,j));
    cout<<dis;
}

日期问题
题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。
小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

输出
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。
多个日期按从早到晚排列。

样例输入
02/03/04

样例输出
2002-03-04
2004-02-03
2004-03-02

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool judge(int year,int month,int day){
  if(!month||month>12)return 0;   //判断月
    if(year%4==0&&year/100!=0||year%400==0){
        months[2]=29;                            //还原          
    }
    if(!day||months[month]<day)return 0;   //判断日
    months[2]=28;
    return 1;

}
int main(){
    int a,b,c;
    scanf("%d/%d/%d",&a,&b,&c);
    for(int i=19600101;i<=20591231;i++){
      int year=i/10000;
    int month=i/100%100;
    int day=i%100;
        if(judge(year,month,day)){
            if(year%100==a&&month==b&&day==c||day==a&&month==b&&year%100==c||month==a&&day==b&&year%100==c){
                printf("%d-%02d-%02d\n",year,month,day);
            }
            
        }
    }
}

航班时间

题目描述
        小 h 前往美国参加了蓝桥杯国际赛。小 h 的女朋友发现小 h 上午十点出发,上午十二点到达美国,于是感叹到“现在飞机飞得真快,两小时就能到美国了”。

        小 h 对超音速飞行感到十分恐惧。仔细观察后发现飞机的起降时间都是当地时间。由于北京和美国东部有 12 小时时差,故飞机总共需要 14 小时的飞行时间。

        不久后小 h 的女朋友去中东交换。小 h 并不知道中东与北京的时差。但是小 h 得到了女朋友来回航班的起降时间。小 h 想知道女朋友的航班飞行时间是多少。

        对于一个可能跨时区的航班,给定来回程的起降时间。假设飞机来回飞行时间相同,求飞机的飞行时间。

输入格式
        从标准输入读入数据。

        一个输入包含多组数据。

        输入第一行为一个正整数 T,表示输入数据组数。

        每组数据包含两行,第一行为去程的起降时间,第二行为回程的起降时间。

        起降时间的格式如下

h1:m1:s1 h2:m2:s2

h1:m1:s1 h3:m3:s3 (+1)

h1:m1:s1 h4:m4:s4 (+2)

        表示该航班在当地时间 `h1` 时 `m1` 分 `s1` 秒起飞,

        第一种格式表示在当地时间 当日 `h2` 时 `m2` 分 `s2` 秒降落

        第二种格式表示在当地时间 次日 `h3` 时 `m3` 分 `s3` 秒降落。

        第三种格式表示在当地时间 第三天 `h4` 时 `m4` 分 `s4` 秒降落。

        对于此题目中的所有以 `h:m:s` 形式给出的时间, 保证(0 ≤ h ≤ 23 ,0 ≤ m,s ≤ 59).

输出格式
        输出到标准输出。

        对于每一组数据输出一行一个时间 `hh:mm:ss`,表示飞行时间为 `hh` 小时 `mm` 分 `ss` 秒。

        注意,当时间为一位数时,要补齐前导零。如三小时四分五秒应写为 `03:04:05`。
 

                      

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int day1,day2,minute1,minute2,sec1,sec2,x;
void gettime(){
    scanf("%d:%d:%d %d:%d:%d (+%d)",&day1,&minute1,&sec1,&day2,&minute2,&sec2,&x);
}
int swt(int a,int b,int c){
     int u=a*3600+b*60+c;
     return u;
}
int main(){
    int n;
    cin>>n;
    while(n--){
        int t=0;
        gettime();
        t+=x*3600*24+swt(day2,minute2,sec2)-swt(day1,minute1,sec1);
        x=0;
        gettime();
        t+=x*3600*24+swt(day2,minute2,sec2)-swt(day1,minute1,sec1);
        t=t/2;
        x=0;
        printf("%02d:%02d:%02d\n",t/3600,t%3600/60,t%60);
        
    }
}

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int day1,day2,minute1,minute2,sec1,sec2,x;
void gettime(){
    string line;
    getline(cin,line);
    if(line.back()!=')')line+=" (+0)";     //归一化处理
    sscanf(line.c_str(),"%d:%d:%d %d:%d:%d (+%d)",&day1,&minute1,&sec1,&day2,&minute2,&sec2,&x);
}
int swt(int a,int b,int c){
     int u=a*3600+b*60+c;
     return u;
}
int main(){
    int n;
    cin>>n;
    string line;
    getline(cin,line);
    while(n--){
        int t=0;
        gettime();
        t+=x*3600*24+swt(day2,minute2,sec2)-swt(day1,minute1,sec1);
        x=0;
        gettime();
        t+=x*3600*24+swt(day2,minute2,sec2)-swt(day1,minute1,sec1);
        t=t/2;
        x=0;
        printf("%02d:%02d:%02d\n",t/3600,t%3600/60,t%60);
        
    }
}

 1241. 外卖店优先级

“饱了么”外卖系统中维护着 N 家外卖店,编号 1∼N。每家外卖店都有一个优先级,初始时 (0时刻) 优先级都为 0。每经过 1个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果优先级小于等于 3,则会被清除出优先缓存。
给定 T时刻以内的 M 条订单信息,请你计算 T时刻时有多少外卖店在优先缓存中。
输入格式
第一行包含 3个整数 N,M,T。
以下 M行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id的外卖店收到一个订单。
输出格式
输出一个整数代表答案。
数据范围
1≤N,M,T≤105,
1≤ts≤T,
1≤id≤N
输入样例:
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
输出样例:
1
样例解释
6时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6,加入优先缓存。所以是有 1
家店 (2 号) 在优先缓存中。

#include<iostream> //超时代码
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int a[N][N];   //第i家店在j时刻的订单数
int w[N];
bool f[N];//第i家店的优先数,与是否是优先店
int main(){
    int n,m,t,ans=0;
    cin>>n>>m>>t;
    while(m--){
        int i,j;
        cin>>i>>j;
        a[j][i]++;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=t;j++){
            if(a[i][j]){
                w[i]+=a[i][j]*2;
                if(w[i]>5){
                    f[i]=1;
                }
                
            }
            else{
                if(w[i]>0){
                    w[i]--;
                }
                if(w[i]<=3){
                    f[i]=0;
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(f[i]){
            ans++;
        }
    }
    cout<<ans;
}

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define x first
#define y second
using namespace std;
const int N=1e5+10;
typedef pair<int,int>PII;

PII order[N];
bool f[N];//是否是优先店
int main(){
    int n,m,T,ans=0;
    cin>>n>>m>>T;
    for(int i=0;i<m;i++){
        scanf("%d %d",&order[i].y,&order[i].x);
    }
    sort(order,order+m);
    bool flag=false;
    int cur=2;
    for(int i=1;i<=m;i++){
        if(order[i].x!=order[i-1].x){
              if(flag && cur - (T - order[i-1].y) > 3)    ans++;      //注意判断末订单时间
            flag = false;   //恢复初始值,为当前集合服务
            cur = 2;
        }
        else{
            int t=order[i].y-order[i-1].y-1;
            if(t==-1){
                t=0;
            }
            cur = max(0, cur - t);
            if(cur <= 3)    flag = false;
            cur += 2;
            if(cur > 5)     flag = true;
        }
    }
    
    cout<<ans;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值