在线评测链接
题目描述
最近塔子哥正在研究什么是虚拟化内存,于是塔子哥想自己亲自动手试一试,你能帮助他吗?
实现一个地址范围为32G,可在范围内任意位置进行数据读写的虚拟化内存机制,数据默认清零。
功能:
- 读写任意地址数据;
- 往任意地址写入任意数据;
- 清空数据,并释放内存;
PS:一个地址空间存一个数据,各地址空间独立
输入描述
输入格式:Command Address Length Data
1、Command为Read、Write、Clear之一
2、Address采用64位无符号十六进制数,全大写
3、Length采用64位无符号十进制数,单位为“字节”
4、Data采用字节流(2个16进制数表示一个Byte),全大写;
5、如果指定的Length大于实际给定的Data,需要程序自行未尾补0,小于则末尾截断
每条指令一行,一个用例输入可以是多条指令混合,只有Read指令有输出。
每个用倒保证指令、参数格式正确,但不保证参数范围,需要程序照题目规格要求自行校验,参数不合法,则对应的指令无效。
每个用例保证需要存储的总数据量最大不超过16MB。一个用例最多不超过500条指令。
例如(3表示有3条指令)
3
Write 0x100 7 001122AA
Read 0x100 4
Clear
输出描述
采用字节流(2个16进制数表示一个Byte),全大写
例如
001122AA
每条Read指令对应一行输出数据,如果指令给的参数不合法,对应的输出为空(不换行)。
样例
输入1
1
Read 0x100 4
输出1
00000000
说明
0x100地址空间未被写入数据,默认返回全0,一共4个字节
输入2
3
Write 0x100 8 00001122AABBCCDD
Read 0x100 12
Clear
输出2
00001122AABBCCDD00000000
说明
0x100地址,前8个字节被写入了有效数据00001122AABBCCDD,读取0x100地址12字节数据,后4个字节补齐默认数0,因此结果为00001122AABBCCDD00000000
思路:哈希表模拟
观察数据规模,存储的数据量不超过16MB,即为 2 24 2^{24} 224,因此可以使用哈希表来存储
- 执行
Clear
操作时,清空哈希表即可 - 执行
Write
操作时,按位置写入每个字节 - 执行
Read
操作时,首先需要判断哈希表中是否存在,如果不存在,使用00
代替,
每次执行Write
和Read
操作时,都需要判断输入的长度
l
e
n
len
len是否在合法范围,
l
e
n
len
len的合法范围为
0
≤
l
e
n
≤
2
34
0\le len \le 2^{34}
0≤len≤234
时间复杂度
O ( n l o g n ) O(nlogn) O(nlogn)
代码
C++
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
Map<Long, String> m = new HashMap<>();
for (int i = 0; i < n; i++) {
String cmd = scanner.next();
if (cmd.equals("Write")) {
long address = Long.parseUnsignedLong(scanner.next().substring(2), 16);
int length = scanner.nextInt();
String data = scanner.next();
if (data.length() < length * 2) {
char[] chars = new char[length * 2 - data.length()];
Arrays.fill(chars, '0');
data += new String(chars);
}
m.put(address, data);
} else if (cmd.equals("Read")) {
long address = Long.parseUnsignedLong(scanner.next().substring(2), 16);
int length = scanner.nextInt();
if (m.containsKey(address)) {
String data = m.get(address);
if (length * 2 > data.length()) {
char[] chars = new char[length * 2 - data.length()];
Arrays.fill(chars, '0');
data += new String(chars);
} else {
data = data.substring(0, length * 2);
}
System.out.println(data);
} else {
char[] chars = new char[length * 2];
Arrays.fill(chars, '0');
System.out.println(new String(chars));
}
} else if (cmd.equals("Clear")) {
m.clear();
}
}
}
}
python代码
import sys
from collections import defaultdict
def solution(lines):
n = len(lines)
rec = defaultdict(str)
for line in lines:
strs = line.split()
if strs[0]=='Clear':
rec = defaultdict(str)
elif strs[0]=='Write':
add = strs[1]
if len(add)>66:
continue
length = int(strs[2])
if length>16*1024*1024:
continue
data = strs[3]
if len(data)>length*2:
data = data[:length*2]
rec[add] = data
elif strs[0]=='Read':
add = strs[1]
if len(add)>66:
continue
length = int(strs[2])
data = rec[add]
if len(data)>length*2:
print(data[:length*2])
else:
print(data+''.join(['0' for _ in range(length*2-len(data))]))
def main():
n = int(input())
lines = []
for _ in range(n):
lines.append(input())
solution(lines)
main()
Java代码
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.IntStream;
public class Main {
@SuppressWarnings({ "resource" })
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] strs = sc.nextLine().split(",");
int[] arr = Arrays.stream(strs).mapToInt(Integer::parseInt).toArray();
Arrays.sort(arr);
int[] sum = new int[arr.length];
int res = 0;
for (int i = 0; i < arr.length; i++) {
sum[i] = IntStream.of(Arrays.copyOfRange(arr, i, arr.length)).sum();
if (sum[i] > 0) {
res = res + sum[i];
}
}
System.out.println(res);
}
}