首页 > 试题广场 >

牛牛的闹钟

[编程题]牛牛的闹钟
  • 热度指数:32192 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
牛牛总是睡过头,所以他定了很多闹钟,只有在闹钟响的时候他才会醒过来并且决定起不起床。从他起床算起他需要X分钟到达教室,上课时间为当天的A时B分,请问他最晚可以什么时间起床

输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含一个正整数,表示闹钟的数量N(N<=100)。
接下来的N行每行包含两个整数,表示这个闹钟响起的时间为Hi(0<=A<24)时Mi(0<=B<60)分。
接下来的一行包含一个整数,表示从起床算起他需要X(0<=X<=100)分钟到达教室。
接下来的一行包含两个整数,表示上课时间为A(0<=A<24)时B(0<=B<60)分。
数据保证至少有一个闹钟可以让牛牛及时到达教室。


输出描述:
输出两个整数表示牛牛最晚起床时间。
示例1

输入

3 
5 0 
6 0 
7 0 
59 
6 59

输出

6 0
#include <iostream>

using namespace std;

int main()
{
    int N, hi, mi, x, goclass;
    int res = 0;
    cin >> N;
    int getup[N];
    for (int i = 0; i < N; i++)
    {
        cin >> hi >> mi;
        getup[i] = hi * 60 + mi;
    }
    cin >> x >> hi >> mi;
    goclass = hi * 60 + mi;
    for (int i = 0; i < N; i++)
    {
        if (getup[i] + x <= goclass && getup[i] > res)
            res = getup[i];
    }
    cout << res / 60 << ' ' << res % 60;
    return 0;
}

发表于 2018-03-31 09:20:59 回复(4)

第一步:将小时化为分钟,添加到数组里,
第二步:遍历数组 , 遍历的同时分为以下几步  :
1.判断当前时间会不会迟到  也就是 所剩时间 = (到校时间-路程-闹钟)如果小于0肯定迟到了
2.如果大于零,我们找所剩时间最小的(可以等于0) 把 i 的位置赋值给min a[min]就是最迟的闹钟了
3.分钟/60所得的就是小时  分钟%60所得的就是剩下的分钟;


import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int hh = 0 , mm = 0;
        int [] a = new int[N];
        for (int i = 0; i < N; i++) {
            hh = in.nextInt();
            mm = in.nextInt();
            a[i] =( hh * 60 ) + mm;
        }
        int lushi = in.nextInt();
        int ScHH = in.nextInt();
        int ScMM = in.nextInt();
        int School = (ScHH * 60) + ScMM;
        int min = 0;
        for (int i = 0; i < a.length; i++) {
            if(School - (lushi + a[i]) < 0 ){
                continue;
            }else{
                if(School -(lushi + a[i]) < School - (lushi + a[min])){
                    min = i;
                }
            }
        }
        
        System.out.println(a[min]/60+ " " +a[min]%60);
    }
}

发表于 2018-03-28 15:31:01 回复(2)

思路

把时间都转换为分钟计数,上课时间-路上时间得到最晚起床时间,把所有闹钟时间排序后,二分查找最晚起床时间。

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int h=0,m=0;
        int[] a = new int[n];
        for(int i=0;i<n;i++){
            h = sc.nextInt();
            m = sc.nextInt();
            a[i] = h*60+m;
        }
        int t = sc.nextInt();
        h = sc.nextInt();
        m = sc.nextInt();
        int p = h*60+m-t;
        Arrays.sort(a);
        t = Arrays.binarySearch(a,p);
        if(t <0) t = -(t+2);
        h = a[t]/60;
        m = a[t]%60;
        System.out.print(h+" "+m);
    }
}
发表于 2018-03-28 11:17:54 回复(12)
python就要有python的样子,非常pythonic的写法
import bisect
tomins = lambda h, m: h * 60 + m
formats = lambda time: (time // 60, time % 60)

n = int(input())
clocks = [tomins(*list(map(int, input().split()))) for i in range(n)]

clocks.sort()
dist = int(input())
schedule = tomins(*list(map(int, input().split())))
idx = bisect.bisect(clocks, schedule - dist)
print(*formats(clocks[idx - 1]))


发表于 2019-09-08 11:33:58 回复(0)
思路:把含小时和分钟时间都转换成以分钟为单位的时间,然后判断闹钟时间是否满足题意,并找出最晚的闹钟时间,最后转换成含小时和分钟的时间输出即可。

#include<iostream>
using namespace std;
int main(){
	int N,Hi,Mi,x,time[100],A,B;
	cin>>N;
	for(int i=0;i<N;i++){
		cin>>Hi>>Mi;
		time[i]=Hi*60+Mi;
	}
	cin>>x;
	cin>>A>>B;
	int classtime=A*60+B; 
	int latest=0;
	for(int i=0;i<N;i++){
		if( (time[i]+x<=classtime)&&(time[i]>latest) ){
			latest=time[i];
		}
	}
	Mi=latest%60;
	Hi=latest/60;
	cout<<Hi<<" "<<Mi<<endl;
}



发表于 2020-02-08 10:10:40 回复(0)

本套8道题全部pass的C++代码已挂到了我的GitHub(https://github.com/shiqitao/NowCoder-Solutions)
牛客网上的其他题目解答也在持续更新。

#include <iostream>
using namespace std;
int main()
{
    int n; cin >> n;
    int max_h = 0, max_m = 0, maxTime = 0;
    int *hour = new int[n];
    int *minute = new int[n];
    int *time = new int[n];
    for (int i = 0; i < n; i++) {
        cin >> hour[i] >> minute[i];
        time[i] = hour[i] * 60 + minute[i];
    }
    int X; cin >> X;
    int reach_h, reach_m; cin >> reach_h >> reach_m;
    int reachTime = reach_h * 60 + reach_m;
    for (int i = 0; i < n; i++) {
        if (time[i]>maxTime && time[i] + X <= reachTime) {
            maxTime = time[i];
            max_h = hour[i];
            max_m = minute[i];
        }
    }
    cout << max_h << " " << max_m;
    delete[] hour;
    delete[] minute;
    delete[] time;
    return 0;
}
发表于 2018-03-28 19:15:46 回复(0)
n = int(input())
clock = []
for _ in range(n):
    temp = input()
    hm = list(map(int, temp.split()))
    # 以0点0分为原点,将所有闹钟时间转换为绝对时间
    clock.append([temp, hm[0] * 60 + hm[1]])
# 到教室需要花费的时间
time_cost = int(input())
# 将上课时间也转换为绝对时间
hm = list(map(int, input().split()))
target = hm[0] * 60 + hm[1]
# 过滤掉会迟到的闹钟时间
clock = [item for item in clock if item[1] + time_cost <= target]
# 选择最接近上课时间的闹钟时间
print(sorted(clock, key=lambda x: target - x[1])[0][0])

发表于 2020-11-25 15:08:03 回复(0)
pair自动先比较fisrt再比较second
#include<bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<pair<int,int>> v(n);
    for(int i=0;i<n;i++) {
        cin >> v[i].first >> v[i].second;
    }
    sort(v.begin(), v.end());
    int dt;
    cin >> dt;
    pair<int,int> dead;
    cin >> dead.first >> dead.second;
    for(int i=1;i<n;i++) {
        int carry = (v[i].second + dt)/60;
        int val = (v[i].second + dt)%60;
        int new1 = v[i].first + carry;
        int new2 = val;
        if(new1 > dead.first || 
           (new1==dead.first && new2>dead.second)
          ) {
            cout << v[i-1].first << " " << v[i-1].second << endl;
            break;
        }
    }
    return 0;
}
话说这题数据要是跨24小时就麻烦了

发表于 2020-06-12 00:50:02 回复(0)
这一道题顺序便利牛牛定的闹钟,找到最晚时间即可,(注意用sort排序下闹钟即可)
#include<iostream>
(720)#include<algorithm>
using namespace std;
struct time{
    int h,min;
};
int cmp(struct time a,struct time b){
    if(a.h<b.h){
        return 1;
    }else if(a.h==b.h){
        if(a.min<b.min){
            return 1;
        }else{
            return 0;
        }
    }else{
        return 0;
    }
}
int main(){
    int n,x;
    struct time t[105];
    struct time s;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>t[i].h>>t[i].min;
    }
    sort(t,t+n,cmp);
    cin>>x;
    cin>>s.h>>s.min;
    int flag=0;
    for(int i=0;i<n;i++){
        int temph,tempmin;
        temph=t[i].h+(t[i].min+x)/60;
        tempmin=(t[i].min+x)%60;
        if((temph<s.h)||(temph==s.h&&tempmin<=s.min))continue;
        else{
            cout<<t[i-1].h<<" "<<t[i-1].min<<endl;
            flag=1;
            break;
        }
    }
    if(flag==0)cout<<t[n-1].h<<" "<<t[n-1].min<<endl;
    return 0;
}


编辑于 2020-05-15 11:42:54 回复(0)
import java.util.Arrays;
import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //输入闹钟个数
        int n = sc.nextInt();
        int[] clock = new int[n];
        //输入闹钟时间
        for (int i = 0; i < n; i++) {
            int hour = sc.nextInt();
            int minute = sc.nextInt();
            clock[i] = hour*60 + minute;
        }
        Arrays.sort(clock);

        int walkTime = Integer.parseInt(sc.next());
        int hour = sc.nextInt();
        int minute = sc.nextInt();
        int classTime = hour*60+minute;
        int getupTime = classTime-walkTime;

        int i = n-1;
        //如果闹钟大于起床时间,继续往下找到最晚起床时间
        while (getupTime < clock[i]){
            i--;
        }
        System.out.println(clock[i]/60+" "+clock[i]%60);
    }
}

发表于 2020-04-12 12:56:40 回复(0)
JavaScript(Node) 😎题目:网易-牛牛的闹钟
//单位转换 遍历数组  clockArr[j]> 上课时间schoolTimeMax - 赶路时间x
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})
let inArr = []
rl.on('line', line=>{
    if(!line) return
    inArr.push(line.trim())
    let len = inArr.length
    let n = +inArr[0] //n: alarm number 
    if(len == n+3){
        let x = inArr[len-2]  //x: 起床到教室需要X(0<=X<=100)分钟
        let schoolTime = inArr[len-1].trim().split(' ') //schoolTime:上学时间(h,m)
        let schoolTimeMax = +(schoolTime[0])*60 + +(schoolTime[1])
        let clockArr = []; //clockArr: n行 data
        //遍历 n行闹钟数的 data
        for(let i=0;i<n;i++){
            let clock = inArr[i+1].trim().split(' ')
            clockArr[i] = +(clock[0])*60 + +(clock[1])
        }
        clockArr.sort((a,b)=>a-b)
        for(let j=clockArr.length-1;j>=0;j--){
            if(clockArr[j] > (schoolTimeMax-x)) continue
            else {
                console.log(Math.floor(clockArr[j] / 60), clockArr[j] % 60)
                break
            }
        }
    }
})


发表于 2020-02-26 10:06:57 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        int[] arr=new int[N];
        for(int i=0;i<N;i++){
            int Hi=sc.nextInt();
            int Mi=sc.nextInt();
            arr[i]=Hi*60+Mi;
        }
        Arrays.sort(arr);
        int X=sc.nextInt();
        int A=sc.nextInt();
        int B=sc.nextInt();
        int sk=A*60+B;
        for(int i=0;i<N;i++){
            int t=sk-X-arr[i];
            if(t==0){
                System.out.print(arr[i]/60+" "+arr[i]%60);
                break;
            }
            if(t<0){
                System.out.print(arr[i-1]/60+" "+arr[i-1]%60);
                break;
            }
        }
    }
}

发表于 2020-02-25 11:08:55 回复(1)

1 思路

  1. 先将所有的闹钟时间按照从早到晚排序。

  2. 通过上课时间和赶路时间计算出最晚起床时间。

  3. 用二分查找在所有闹钟时间中找最晚起床时间,如果找到则直接输出,如果没找到就输出插入位置前一个闹钟。

2 代码

import java.util.Scanner;
import java.util.Arrays;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        Integer[][] alarms = new Integer[N][2];
        for (int i = 0; i < N; ++i) {
            alarms[i][0] = scanner.nextInt();
            alarms[i][1] = scanner.nextInt();
        }
        
        // 对闹钟进行排序
        Arrays.sort(alarms, (Integer[] a1, Integer[] a2)->{
            // 如果时不相等就返回时的比较结果
            if (a1[0].compareTo(a2[0]) != 0) {
                return a1[0].compareTo(a2[0]);
            } else {
                // 否则返回分的比较结果
                return a1[1].compareTo(a2[1]);
            }
        });
        
        int X = scanner.nextInt();
        int A = scanner.nextInt();
        int B = scanner.nextInt();
        
        // 算出最晚起床时间
        A -= X / 60;
        X %= 60;
        if (B >= X) {
            B -= X;
        } else {
            --A;
            B = B + 60 - X;
        }
        Integer[] getUp = {A, B};
        
        // 用二分查找在所有闹钟时间中查找起床时间
        int result = Arrays.binarySearch(alarms, getUp, (Integer[] a1, Integer[] a2)->{
            // 如果时不相等就返回时的比较结果
            if (a1[0].compareTo(a2[0]) != 0) {
                return a1[0].compareTo(a2[0]);
            } else {
                // 否则返回分的比较结果
                return a1[1].compareTo(a2[1]);
            }
        });
        
        // 如果正好找到就输出此闹钟
        if (result >= 0) {
            System.out.println(alarms[result][0] + " " + alarms[result][1]);
        } else {
            // 如果没有恰好相等的,返回的是恰好大于起床时间的那个闹钟的 - index - 1,
            // 所以要输出 - result - 2 位置的闹钟。
            System.out.println(alarms[- result - 2][0] + " " + alarms[- result - 2][1]);
        }
    }
}


发表于 2019-11-21 11:17:18 回复(0)
首先需要根据去教室用的时间和上课时间来计算最晚起床的准确时间,然后从闹钟里面找最适合的一个(注意 存放闹钟的数组需要排好序才能查找)
import java.util.*;
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner (System.in);
		int n=cin.nextInt();//闹钟数量
		int a[][]=new int[n][2];
		for(int i=0;i<n;i++) {
			a[i][0]=cin.nextInt();//当天的A时B分中的A
			a[i][1]=cin.nextInt();//当天的A时B分中的B
		}
		int c[][]=new int[1][2];
        int x=cin.nextInt();//去教室需要用到的时间
        int b[][]=new int [1][2];//上课时间A时B分
        b[0][0]=cin.nextInt();
        b[0][1]=cin.nextInt();
        if(x<b[0][1]) {
        	c[0][0]=b[0][0];
        	c[0][1]=b[0][1]-x;
        	
        }
        else if(x==b[0][1]) {
        	c[0][0]=b[0][0];
        	c[0][1]=0;
        }
        else {
        	if(x-b[0][1]<=60) {
        		c[0][0]=b[0][0]-1;
            	c[0][1]=60-(x-b[0][1]);	
        	}
        	else {
        		c[0][0]=b[0][0]-2;
            	c[0][1]=60-(x-b[0][1]-60);	
        		
        	}
        }
        
        for (int i = 1; i < n; i++) {
			int temp0 = a[i][0];// 待插入的值
			int temp1 = a[i][1];// 待插入的值
			
			int index = i;// 待插入的位置
			while ((index > 0 && a[index - 1][0] > temp0) || (index > 0 && (a[index - 1][0] == temp0 && index > 0 && a[index - 1][1] > temp1)  )) {
			a[index][1] = a[index - 1][1];// 待插入的位置重新赋更大的值
			a[index][0] = a[index - 1][0];
			
			index--;// 位置往前移
			}
			a[index][1] = temp1;
			a[index][0] = temp0;
			}
       
         int temp[][]=new int[1][2];
        for(int i=0;i<n;i++) {
        	if(c[0][0]<a[i][0] || (c[0][0]==a[i][0]  && c[0][1]<a[i][1]))break;
        	temp[0][0]=a[i][0];
        	temp[0][1]=a[i][1];
        }

        System.out.print(temp[0][0]+" "+temp[0][1]);
		
	}

}

发表于 2019-11-02 23:04:37 回复(0)
个人感觉就是一个vector的自定义排序。
思路:将所有输入首先按时进行升序排序,当时相同时按分进行升序排序,最后判断时从最后一个往前看是否满足,可以直接return掉。
#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;
bool cmp(vector<vector<int>> vec1, vector<vector<int>> vec2)
{
    return vec1[0] < vec2[0];//按时进行排
    return vec1[1] < vec2[1];//当时相等时,按分进行排
}
int main()
{
    int n;
    int h, min;
    int need_time;//需要的时间
    int class_h, class_min;//上课时间
    int temp_h, temp_min;//进行计算后的时间,用于与上课时间进行比较
    vector<vector<int>> mp;//之前用的mp,然后考虑到当多个时相同时不能筛掉,然后使用了multimap时发现不能在时相同时按分进行排;
    cin >> n;
    while (n--)
    {
        cin >> h >> min;
        mp.push_back({ h, min });//放进vector
    }
    sort(mp.begin(), mp.end());//按自定义的规则进行排序
    cin >> need_time;
    cin >> class_h >> class_min;
    int it = mp.size();
    it--;
    while (1)
    {
        temp_min = (mp[it][1] + need_time) % 60;
        temp_h = mp[it][0] + (mp[it][1] + need_time) / 60;
        if (temp_h < class_h || (temp_h == class_h && temp_min <= class_min))
        {
            cout << mp[it][0] << " " << mp[it][1] << endl;
            return 0;
        }
        it--;
    }
    return 0;
}
发表于 2019-10-30 21:33:51 回复(0)
最容易理解的解法:将小时数转换为分钟数,比较完了,再转换回来
(由于题干不清楚的问题,我以为闹钟是按顺序给出的。)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int [] a=new int[n];
        for(int i=0;i<n;i++){
            a[i]=sc.nextInt()*60+sc.nextInt();
        }
        int x=sc.nextInt();
        int A=sc.nextInt()*60+sc.nextInt();
        int ans=0;
        Arrays.sort(a);
        for(int i=n-1;i>=0;i--){
            if(a[i]<=A-x){ans=a[i];break;}
        }
        System.out.println(ans/60+" "+ans%60);
    }
}

发表于 2019-09-18 11:56:44 回复(1)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> p;
int main()
{
	int N;cin >> N;
	p time[N];
	for (int i = 0;i < N;i++)
        cin >> time[i].first >> time[i].second;
    
	sort(time, time + N);
	int X;cin >> X;
	int A, B;cin >> A >> B;

	//计算它最晚的起床时间
	if (B - X >= 0)
		B = B - X;
	else
	{
		A -= 1;
		B = B - X + 60;
	}

	//和闹钟比较
	for (int i = N - 1;i >= 0;i--)
	{
		if (time[i].first < A||(time[i].first == A && time[i].second <= B))
		{
			cout << time[i].first<<' ' << time[i].second << endl;
			break;
		}
	}

	return 0;

}
别人的做法都是先转分钟再算,我这个是用pair来存储时钟和分钟,通过条件比较,比较条件会稍微比直接比分钟复杂,不过总体还好
发表于 2019-09-08 14:46:24 回复(0)
import java.util.*;
//1.将输入的闹钟时间转换成分钟数存入矩阵,方便计算
//2.将上课时间减去到达教室所需时间,得到起床时间
//3.由于只有闹钟响时才决定起不起床,因此在小于等于起床时间的所有闹钟里面,最大的那个就是我们需要的最晚闹钟时间
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        //时间转换成分钟数
        int[] minutes = new int[N];
        int hour = 0;
        int minute = 0;
        for(int i = 0; i < N; i++){
            hour = sc.nextInt();
            minute = sc.nextInt();
            minutes[i] = hour * 60 + minute;
        }
        int needTime = sc.nextInt();
        hour = sc.nextInt();
        minute = sc.nextInt();
        int classTime = hour * 60 + minute;
        //得到最晚起床时间
        int lastMinute = classTime - needTime;
        //设置一个max,在小于等于起床时间的闹钟时间里,更新最大的闹钟时间为max
        int max = 0;
        for(int i = 0; i < N; i++){
            if(lastMinute >= minutes[i]){
                max = Math.max(max, minutes[i]);
            }
        }
        //转换成时间
        hour = max / 60;
        minute = max % 60;
        System.out.print(hour + " " + minute);
    }
}

发表于 2019-09-03 10:15:51 回复(0)
1.将所有闹钟时间转换成分钟形式,存入集合中
2.遍历集合,判断该事件是否满足不迟到,如果满足,再判断是否为为最晚闹钟,如果是,标记该闹钟。
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int n = sc.nextInt();
			ArrayList<Integer> array = new ArrayList<Integer>();
			for(int i = 0;i<n;i++) {
				int p = sc.nextInt();
				int q = sc.nextInt();
				array.add(p*60+q);
			}
			int need = sc.nextInt();
			int hour = sc.nextInt();
			int second = sc.nextInt();
			int overTime = hour*60 + second;
			int num = 0;
			int abs = overTime;
			for(int i =0;i<n;i++) {
				if((array.get(i)+need)<=overTime) {
						if(overTime-(array.get(i)+need)<=abs) {
							abs = overTime-(array.get(i)+need);
							num = i;
						}	
				}
			}		
			System.out.println(array.get(num)/60 + " "+array.get(num)%60);
		}
	}
}


编辑于 2019-08-26 16:49:07 回复(1)
import sys
def plus_time(t,x):
    if t[1]+x<60:
        return [t[0],t[1]+x]
    else:
        return [t[0]+1,t[1]+x-60]
    
if __name__=='__main__':
    n=int(sys.stdin.readline().strip())
    time=[]
    for i in range(n):
        time.append(list(map(int,sys.stdin.readline().split())))
    x=int(sys.stdin.readline().strip())
    start=list(map(int,sys.stdin.readline().split()))
    time=sorted(time,key=lambda x:x[::1])
    i=0
    while i<len(time):
        if plus_time(time[i],x)[0]<start[0]:
            i+=1
        elif plus_time(time[i],x)[0]==start[0] and plus_time(time[i],x)[1]<=start[1]:
            i+=1
        else:
            print(' '.join(map(str,time[i-1])))
            break
    

发表于 2019-08-21 11:29:53 回复(0)

热门推荐

通过挑战的用户

查看代码