IGMP 协议中,有一个字段称作最大响应时间(Max Response Time),HOST收到查询报文,解析出MaxResponseTime字段后,
需要在(0,MaxResponseTime)(s)时间内选取随机时间回应一个响应报文,如果再随机时间内收到一个新的查询报文,则会根据两者时间的大小,选取小的一方刷新回应时间。
MaxRespCode < 128
,MaxRespTime = MaxRespCode
;MaxRespCode >= 128
,MaxRespTime = (amnt | 0x10) << (exp + 3)
;|0|123|4567|
|1|exp|mant|
exp
最大响应时间的高5~7位
;mant
为最大响应时间的低4位
。其中接收到的 MaxRespCode 最大值为255,以上出现所有字段均为无符号数。
现在我们认为 HOST 接收到查询报文时,选取的随机时间必定为最大值。
现给出 HOST 收到查询报文个数 ,HOST收到报文的时间 ,以及查询报文的最大响应时间字段值 ,请计算出 HOST 发送响应报文的时间。
第一行为查询报文个数 ,后续每行分别为HOST收到报文时间 ,以及最大响应字段 ,以空格分割。
HOST发送响应报文的时间
3
0 20
1 10
8 20
11
收到3个报文,
第0秒收到1个报文响应时间为20秒,则要到0+20=20秒响应;
第1秒收到第2个报文,响应时间为10,则要到1+10=11秒响应,与上面的报文的响应时间比较获得响应时间最小为11秒;
第8秒收到第3个报文,响应时间为20秒,则要到8+20=28秒响应,与上面的报文的响应时间比较获得响应时间最小为11秒;
最终得到最小响应报文时间为11秒。
2
0 255
200 60
260
第0秒收到第1个报文,响应时间为255秒,则要到(15|0x10)<<(7+3)=31744秒响应;(mant=15,exp=7)
第200秒收到第2个报文,响应时间为60,则要到200+60=260秒响应,与上面的报文的响应时间比较获得响应时间最小为260秒;
最终得到最小响应报文时间为260秒。
用例确定只会发送一个响应报文,不存在计时结束后依然收到查询报文的情况。
本题的目标是计算出在给定一系列查询报文的情况下,HOST 发送响应报文的最早时间。每个查询报文包含报文时间和最大响应时间字段。这个问题可以通过迭代处理每个查询报文并不断更新最小响应时间来解决。
(mant | 0x10) << (exp + 3)
计算最大响应时间。由于我们需要迭代处理每个查询报文,所以算法的时间复杂度为 O(C),其中 C 为查询报文的数量。在每次迭代中,我们仅执行常数时间的操作,如计算最大响应时间和更新最小响应时间。因此,总体时间复杂度为 O(C)。
算法所需的额外空间主要用于存储输入数据。除此之外,只需要常数级别的额外空间来存储临时变量,如报文时间、最大响应代码和当前报文的响应时间。因此,总体空间复杂度为 O(C)。
总结,本题的解题思路是迭代处理每个查询报文并不断更新最小响应时间。算法具有 O(C) 的时间复杂度和 O(C) 的空间复杂度。在实际实现中,可以使用不同的编程语言,如 C、C++、Python、JavaScript(Node.js)或 Go。不同语言的实现细节可能略有不同,但总体解题思路和复杂度分析保持一致。
#include <stdio.h>
#include <stdlib.h>
unsigned int max_response_time(unsigned int max_resp_code) {
if (max_resp_code < 128) {
return max_resp_code;
}
unsigned int mant = max_resp_code & 0x0F;
unsigned int exp = (max_resp_code >> 4) & 0x07;
return (mant | 0x10) << (exp + 3);
}
int main() {
int C;
scanf("%d", &C);
unsigned int min_resp_time = (unsigned int)-1;
for (int i = 0; i < C; i++) {
unsigned int T, M;
scanf("%u %u", &T, &M);
unsigned int resp_time = T + max_response_time(M);
if (resp_time < min_resp_time) {
min_resp_time = resp_time;
}
}
printf("%u\n", min_resp_time);
return 0;
}
#include <iostream>
#include <limits>
unsigned int max_response_time(unsigned int max_resp_code) {
if (max_resp_code < 128) {
return max_resp_code;
}
unsigned int mant = max_resp_code & 0x0F;
unsigned int exp = (max_resp_code >> 4) & 0x07;
return (mant | 0x10) << (exp + 3);
}
int main() {
int C;
std::cin >> C;
unsigned int min_resp_time = std::numeric_limits<unsigned int>::max();
for (int i = 0; i < C; i++) {
unsigned int T, M;
std::cin >> T >> M;
unsigned int resp_time = T + max_response_time(M);
if (resp_time < min_resp_time) {
min_resp_time = resp_time;
}
}
std::cout << min_resp_time << std::endl;
return 0;
}
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* <br>Author: Amos
* <br>E-mail: amos@amoscloud.com
* <br>Date: 2023/3/22
* <br>Time: 10:20
* <br>Description: 100%
*/
public class Main0229 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int C = scanner.nextInt();
int[] T = new int[C];
int[] M = new int[C];
for (int i = 0; i < C; i++) {
T[i] = scanner.nextInt();
M[i] = scanner.nextInt();
}
int responseTime = solution(C, T, M);
System.out.println(responseTime);
}
}
private static int solution(int C, int[] T, int[] M) {
int responseTime = 0;
for (int i = 0; i < C; i++) {
int maxRespTime = calculateMaxRespTime(M[i]);
int newRespTime = T[i] + maxRespTime;
if (i == 0 || newRespTime < responseTime) {
responseTime = newRespTime;
}
}
return responseTime;
}
private static int calculateMaxRespTime(int maxRespCode) {
if (maxRespCode < 128) {
return maxRespCode;
} else {
int exp = (maxRespCode & 0x70) >> 4;
int mant = maxRespCode & 0x0F;
return (mant | 0x10) << (exp + 3);
}
}
}
def max_response_time(max_resp_code):
if max_resp_code < 128:
return max_resp_code
mant = max_resp_code & 0x0F
exp = (max_resp_code >> 4) & 0x07
return (mant | 0x10) << (exp + 3)
if __name__ == "__main__":
C = int(input())
min_resp_time = float('inf')
for _ in range(C):
T, M = map(int, input().split())
resp_time = T + max_response_time(M)
min_resp_time = min(min_resp_time, resp_time)
print(min_resp_time)
const readline = require('readline');
function maxResponseTime(maxRespCode) {
if (maxRespCode < 128) {
return maxRespCode;
}
const mant = maxRespCode & 0x0F;
const exp = (maxRespCode >> 4) & 0x07;
return (mant | 0x10) << (exp + 3);
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let C;
let count = 0;
let minRespTime = Infinity;
rl.on('line', (input) => {
if (C === undefined) {
C = parseInt(input);
} else {
const [T, M] = input.split(' ').map(Number);
const respTime = T + maxResponseTime(M);
minRespTime = Math.min(minRespTime, respTime);
count++;
if (count === C) {
console.log(minRespTime);
rl.close();
}
}
});
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func maxResponseTime(maxRespCode uint) uint {
if maxRespCode < 128 {
return maxRespCode
}
mant := maxRespCode & 0x0F
exp := (maxRespCode >> 4) & 0x07
return (mant | 0x10) << (exp + 3)
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
C, _ := strconv.Atoi(scanner.Text())
minRespTime := uint(1<<63 - 1)
for i := 0; i < C; i++ {
scanner.Scan()
line := scanner.Text()
parts := strings.Split(line, " ")
T, _ := strconv.Atoi(parts[0])
M, _ := strconv.Atoi(parts[1])
respTime := uint(T) + maxResponseTime(uint(M))
if respTime < minRespTime {
minRespTime = respTime
}
}
fmt.Println(minRespTime)
}