华为8/10/1-内存管理

1、内存管理
有n个可用的内存段组成的内存段列表N,每一段内存用起始地址starti和长度
leni表示,start和len单位均为M,通过对某个内存地址进行读写一致性校
验,可确认内存是否存在问题,根据测试结果,支持对内存段列表进行如下两种操作:
(1)剔除一段内存
如果地址a读写校验错误,则需要把地址a前后2M内存从内存段列表中剔除,
用操作码-a表示从列表中剔除地址a前后2M内存
(2)添加一段内存
如果地址a读写校验正确,则需要把地址a前后2M内存添加到内存段列表中用操作码a表示添加地址a前后2M内存到内存列表中。
对给定的内存段列表N进行m次添加或别除操作之后,请输出最终的可用内存段个数i及内存段列表J。注意事项如下说明
说明:
(1)初始内存段已经保证按照内存段起始地址从小到大排列、相互之间不重叠。
(2)最终输出内存段也需要保证没有重叠和连续区间,也就是说如果存在重蓉区域或者连续需要合并处理
(3)程序中所有输入都按照32位有符号整形处理
(4)如果剔除内存段只有一部分在列表中只需要把存在部分剔除即可。
(5)题目中涉及到的内存地址范围限定在[0~4096M)。每个数字代表从该数字开始的1M内存,也就是说内存最大为4095M开始的1M内存,更大的内存范围不用考虑。
(6)a可以是初始内内存段中存在的地址,也可以不是,不用考虑操作码a=0的场景(0<a<4096)。

输入
1.第1行:初始可用内存段个数n(0<=n<=5)
2.第2行到第n+1行:每一行有两个数用空格做为分隔符,第一个数为starti
第二个数为leni(1<=j<=n0<=start<40960<leni+starti<=4096)}
start1 len1
start2 len2
.....
startn lenn
3.第n+2行:内存操作(剔除或者添加)次数m(1<=m<0) m
4.第n+3行:m个操作码,用空格作为分隔符。排在后面的操作都以前面一次操作的结果为基础 a1 a2 a3 .…. am

输出
输出可用内存段个数及按照内存段起始地址从小到大的顺序输出可用内存段列表
第1行:可用内存段个数
第2行到第j+1行:可用内存段列表J,每一行有两个,用空格做为分隔符。第一个数为starti,第二个数为len
一个数为starti,第二个数为len


样例1
输入:
1 10 1
0 1024 11
2
-10 2000
输出:
3
0 8
12 1012
1998 4
解释:输入表示起始有一段内存:基地址为0M,长度为1024M。有2次内存操
作:第一次为剔除10M地址前后2M内存,即8M地址开始的4M内存,第二次为添加地址2000的前后2M内存,即1998M地址开始的4M内存,所以经过两次操作之后,内存段变为3段。

样例2
输入:
2
0 9
100 900
3
10 120 -2000
输出:
2
0 12
100 900
解释:输入两段内存,有3次内存操作。(1)添加10M前后2M之后,第一段内
存扩展为012。(2)120M前后2M已经在列表中不需要处理。 (3)剔除地址2000M前后2M内存,即1998M起始的4M内存(1998 1999 2000 2001),内存列表中本就不存在不用处理。所以输出列表依然为两段内存
public class HuaWei1 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[] nums=new int[4096];
        for (int i = 0; i < n; i++) {
            int t1=sc.nextInt();
            int t2=sc.nextInt();
            for (int j = t1; j <t1+t2 ; j++) {
                nums[j]=1;
            }
        }
        int m=sc.nextInt();
        for (int i = 0; i < m; i++) {
            int a=sc.nextInt();
            boolean flag=false;
            if(a<0){
                flag=true;
                a=-a;
            }
            for (int j = (a-2)<0?0:a-2; j <((a+2)<4096?a+2:4095); j++) {
                if(flag)
                    nums[j]=0;
                else
                    nums[j]=1;
            }
        }
        List<List<Integer>> res=new LinkedList<>();
        int start=0,end=1;
        for (; start < 4096; start++) {
            if(nums[start]==0)
                start++;
            else
                break;
        }
        end=start+1;
        //System.out.println(start);
        while(end<4096) {
            if(nums[end]==1&&nums[end-1]==0){
                start=end;
            }
            if(nums[end]==0&&nums[end-1]==1){
                List<Integer> tmp=new LinkedList<>();
                tmp.add(start);
                tmp.add(end-start);
                res.add(tmp);
            }
            end++;
        }
        int count=res.size();
        System.out.println(count);
        for (List<Integer> r:res) {
            System.out.println(r.get(0)+" "+r.get(1));
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值