首页 > 试题广场 >

酒店价格

[编程题]酒店价格
  • 热度指数:15399 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
酒店房间的价格录入是通过时间段来录入的,比如10月1日至10月7日800元,10月8日至10月20日500元,请实现以下函数int[][] merge(int[][] dateRangePrices),输入是某个酒店多个日期段的价格,每个日期段(终止日期大于等于起始日期)和对应的价格使用长度为3的数组来表示,比如[0, 19, 300], [10, 40, 250]分别表示从某天开始第1天到第20天价格都是300,第11天到第41天价格都是250,这些日期端有可能重复,重复的日期的价格以后面的为准, 请以以下规则合并并输出合并结果:
1.相邻两天的价格如果相同,那么这两个日期段应该合并
2.合并的结果应该以起始日期从小到大排序

输入描述:
输入数据包括多行,如样例输入所示。


输出描述:
输出数据为一行,如样例输出所示
示例1

输入

1 1 100
2 3 100
4 5 110

输出

[1, 3, 100],[4, 5, 110]
想来想去各种结构中,TreeMap可以用。总感觉还遗留了小bug在里面.
import java.util.*;
public class Main{
    public static void main(String[] args){
       Scanner sc=new Scanner(System.in);
       TreeMap<Integer,Node> map=new TreeMap<>();
        while(sc.hasNext()){
            String[] strs=sc.nextLine().split(" ");
            int start=Integer.parseInt(strs[0]);
            int end=Integer.parseInt(strs[1]);
            int val=Integer.parseInt(strs[2]);
            map.put(start,new Node(start,end,val));
	       map.put(end,new Node(start,end,val));
	       map.subMap(start,false,end,false).clear();
	           
	       if(map.lowerKey(start)!=null) {
	        	int tmpStart=map.lowerKey(start);
	        	int tmpEnd=map.get(tmpStart).getEnd();
	        	int tmpVal=map.get(tmpStart).getVal();
	        	if(end<tmpEnd) {
	        		 map.put(tmpStart, new Node(tmpStart,start-1,tmpVal));
	        		 map.put(start-1, new Node(tmpStart,start-1,tmpVal));
	        		map.put(end+1, new Node(end+1,tmpEnd,tmpVal));
	        		map.put(tmpEnd, new Node(end+1,tmpEnd,tmpVal));
	        	}
	        	if(start<=tmpEnd&&end>=tmpEnd) {
	        		map.put(tmpStart, new Node(tmpStart,start-1,tmpVal));
	        		map.put(start-1, new Node(tmpStart,start-1,tmpVal));
	        	}
	        }
	        if(map.higherKey(end)!=null) {
	        	int tmpStart=map.higherKey(end);
	        	int tmpEnd=map.get(tmpStart).getEnd();
	        	int tmpVal=map.get(tmpStart).getVal();
	        	   
	        	if(tmpStart==tmpEnd&&end<=tmpStart&&end>=map.get(tmpStart).getStart()) {
	        		map.put(end+1, new Node(end+1,tmpEnd,tmpVal));
	        		map.put(tmpEnd, new Node(end+1,tmpEnd,tmpVal));
	        	}
	       }
        }
        StringBuilder sb=new StringBuilder();
        List<Node> list=new ArrayList<>(map.values());

	    int start=list.get(0).getStart();
	    int end=list.get(0).getEnd();
	    int val=list.get(0).getVal();
	    for(int i=1;i<list.size();i++) {
	        int tmpStart=list.get(i).getStart();
	 	    int tmpEnd=list.get(i).getEnd();
	 	    int tmpVal=list.get(i).getVal();
	 	    if(start==tmpStart) {
	 	       continue;
	 	    }
	 	    if(end>=tmpStart-2&&val==tmpVal) {
	 	 	     end=tmpEnd;
	 	 	     continue;
	 	    }
	 	    addResult(sb,start,end,val);
	 	    start=tmpStart;
	 	    end=tmpEnd;
	 	    val=tmpVal;
	    }
	    addResult(sb,start,end,val);
        sb.delete(sb.length()-1,sb.length());
        System.out.println(sb.toString());
        sc.close();
    }
    private static void addResult(StringBuilder sb,int start,int end,int val){
        sb.append("[").append(start).append(", ").append(end).append(", ");
        sb.append(val).append("],");
    }
}

class Node {
    private int start;
	private int end;
	private int value;
		     
	public Node(int start,int end,int value){
        this.start=start;
		this.end=end;
		this.value=value;
	}
	public int getStart(){
	     return start;
	}	  
    
	public int getEnd(){
		return end;
	}
	 public int getVal(){
		return value;
	}
}




编辑于 2021-03-27 23:46:52 回复(0)
import java.util.Scanner;

//用一个数字存储每一天的价格
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = new int[15000];
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int start = in.nextInt();
            int end = in.nextInt();
            int price = in.nextInt();
            for (int i = start; i <= end; i++) {
                arr[i] = price;
            }
        }
        System.out.println(merge(arr));
    }
    //这个传入的数组存储的是每天的价格
    public static String merge(int[] arr)
    {
        String result = "";
        StringBuilder sb = new StringBuilder();
        int size = arr.length;
        int start = 0;
        int end = 0;
        int price = 0;
        int index = 0;
        while (index < size) {
            price = arr[start];
            index++;
            while (index < size && arr[index] == price) {
                index++;
            }
            end = index - 1;
            if (price != 0) {
                sb.append("[").append(start).append(", ").append(end)
                .append(", ").append(price).append("]").append(",");
            }
            //下一次的开始
            start = index;
        }
        sb.deleteCharAt(sb.length() - 1);
        result = sb.toString();
        return result;
    }

}

发表于 2018-09-19 21:30:30 回复(0)
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int[] arr = new int[100000];
        int max = 0;
        while(input.hasNext()){
            int a=input.nextInt();
            int b=input.nextInt();
            if(b>max)
                max=b;
            int c=input.nextInt();
            for(int i=a;i<=b;i++){
                arr[i]=c;
            }
        }
        int index=0;
        while(index<=max){
            if(arr[index]==0)
                index++;
            else{
                int begin = index;
                int value = arr[index];
                while(value==arr[index])
                    index++;
                if(index!=max+1)
                    System.out.print("["+begin+", "+(index-1)+", "+value+"],");
                else
                    System.out.print("["+begin+", "+(index-1)+", "+value+"]");
            }
        }
    }
}

发表于 2018-08-08 21:00:58 回复(1)

/**

  • 题目描述
    酒店房间的价格录入是通过时间段来录入的,比如10月1日至10月7日800元,10月8日至10月20日500元,
    请实现以下函数int[][] merge(int[][] dateRangePrices),输入是某个酒店多个日期段的价格,
    每个日期段(终止日期大于等于起始日期)和对应的价格使用长度为3的数组来表示,
    比如[0, 19, 300], [10, 40, 250]分别表示从某天开始第1天到第20天价格都是300,
    第11天到第41天价格都是250,这些日期端有可能重复,重复的日期的价格以后面的为准, 请以以下规则合并并输出合并结果:
    1.相邻两天的价格如果相同,那么这两个日期段应该合并
    2.合并的结果应该以起始日期从小到大排序
    输入描述:
    输入数据包括多行,如样例输入所示。
    输出描述:
    输出数据为一行,如样例输出所示
    */
    package pastexampaper2017;
    import java.awt.List;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.Scanner;
    class Room implements Comparable{
    private int begin=0;
    private int end=0;
    private int price=0;
    Room(int begin,int end,int price){
     this.begin=begin;
     this.end=end;
     this.price=price;
    
    }
    public int getBegin() {
     return begin;
    
    }
    public void setBegin(int begin) {
     this.begin = begin;
    
    }
    public int getEnd() {
     return end;
    
    }
    public void setEnd(int end) {
     this.end = end;
    
    }
    public int getPrice() {
     return price;
    
    }
    public void setPrice(int price) {
     this.price = price;
    
    }
    public int compareTo(Object room) {
     int diff=this.getPrice()-((Room) room).getPrice();
     if(diff==0) {
         int diff0=this.getEnd()-(((Room) room).getBegin()-1);
         if(diff0==0) {
             return 1;
         }
     }
     return 0;
    
    }
    public String toString() {
      return "[" + this.getBegin() + ", " + this.getEnd()+ ", " + this.getPrice() + "]";
    
    }
    public static Room merge(Room room1,Room room2) {
      if(room1.compareTo(room2)==1) {
          room1.setBegin(room1.getBegin());
          room1.setEnd(room2.getEnd());
          room1.setPrice(room1.getPrice());
          room2.setBegin(0);
          room2.setEnd(0);
          room2.setPrice(0); 
      }else {
          return null;
      }
      return room1;
    
    }
    }
    public class Main12 {
    public static void main(String[] args) {
         Scanner sc=new Scanner(System.in);
         ArrayList list=new ArrayList();
         while (sc.hasNext()){
             int begin = sc.nextInt();
             int end = sc.nextInt();
             int price = sc.nextInt();
             list.add(new Room(begin,end,price));
         }
         //System.out.println(list);
         Object[] obj = list.toArray();
        for(int i=0;i<obj.length;i++){
             for(int j=i;j<obj.length;j++) {
                 Room room1 = (Room) obj[i];
                 Room room2 = (Room) obj[j];
                 Room.merge(room1, room2);
             }
         }
        for(int i=0;i<obj.length-1;i++) {
             if(obj[i].toString().equals("[0, 0, 0]")) {
                 continue;
             }else {
                 System.out.print(obj[i]+",");
             }
        }
        if(obj[obj.length-1].toString().equals("[0, 0, 0]")) {
         return;
     }else {
         System.out.print(obj[obj.length-1]);
     }            
    
    }
    }
    测试用例通过10%,但是我觉得没问题,不知道大家觉得是不是有错误呢
发表于 2018-06-20 11:54:58 回复(0)
//区间树,见算法导论第14章
//用数组暴力模拟的前提是起始日期和终止日期都不会很大
//算是偷鸡的做法
//直接借用了TreeMap,其中key代表日期的起点,value存放一个数据结构(start,end,value)
//我们在向map中插入之前先查询map,把所有本次中覆盖的集合删除掉(有可能会有不完全覆盖的现象,需要处理)
//之后合并连续日期并且价格相同的情况
//以下第一行是添加的输入比如(3, 10, 100)
//第二行是集合中原有的数据比如(1,4,10),(5,6,101),(7,8,19),(9,10,100)
//比如添加 ----------------------------------
//   --------    ----------   ---------   ------
//      ^            ^            ^         ^
//    需要截断       直接删掉     直接删掉     截断
//变成
//  ---|----------------------------------|---
//再判断挨着的是否需要合并
//牛客的数据集是真的菜,模拟居然能过。。。
//另外注意TreeMap的SubMap不是一个真的map,对SubMap的修改会影响TreeMap本身
//以上 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static class Node implements Comparable<Node>{
        int low, high, val;
        public Node(int low, int high, int val) {
            this.low = low;
            this.high = high;
            this.val = val;
        } @Override public int compareTo(Node o) {
            return this.val - o.val;
        }
    }

    public static void insert(TreeMap<Integer, Node> map, Node node) {
        NavigableMap<Integer, Node> subMap = map.subMap(node.low, true, node.high, true);
        while (subMap.size() > 0) {
            Node tmp = subMap.pollFirstEntry().getValue();
            if (subMap.size() == 0 && tmp.low <= node.high && node.high < tmp.high) {
                map.put(node.high + 1, new Node(node.high + 1, tmp.high, tmp.val));
            }
        }
        //check last
        Map.Entry<Integer, Node> entry = map.floorEntry(node.low);
        if (entry != null) {
            Node last = entry.getValue();
            if (last.high > node.high) {
                map.put(node.high + 1, new Node(node.high + 1, last.high, last.val));
            }
            if (last.high >= node.low) {
                last.high = node.low - 1;
            }
            if (last.high == node.low - 1 && last.val == node.val) {
                map.remove(last.low);
                node.low = last.low;
            }
        }
        //check next
        entry = map.ceilingEntry(node.high);
        if (entry != null && entry.getValue().low == node.high + 1 && entry.getValue().val == node.val) {
            map.remove(entry.getValue().low);
            node.high = entry.getValue().high;
        }
        map.put(node.low, node);
    }


    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        TreeMap<Integer, Node> map = new TreeMap<>();
        String line;
        while ((line = br.readLine()) != null) {
            int[] tmp = lineToIntArray(line);
            insert(map, new Node(tmp[0], tmp[1], tmp[2]));
        }
        StringBuffer sb = new StringBuffer();
        int i = 0;
        for (Map.Entry<Integer, Node> entry: map.entrySet()) {
            Node tmp = entry.getValue();
            sb.append("[");
            sb.append(tmp.low);
            sb.append(", ");
            sb.append(tmp.high);
            sb.append(", ");
            sb.append(tmp.val);
            sb.append("]");
            if (++i != map.size())
                sb.append(",");
        }
        System.out.println(sb);
    }

    public static int[] lineToIntArray(String line) {
        String[] arr = line.trim().split(" ");
        int[] ans = new int[arr.length];
        for (int i = 0; i < arr.length; i++)
            ans[i] = Integer.parseInt(arr[i]);
        return ans;
    }
}

编辑于 2018-04-06 20:30:55 回复(0)

用一个table[i][j]数组表示i到j的价格,根据题意往数组里面填价格,最后搜索table里面有价格的元素,组合一下输出。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] table = new int[100000];
        int start = 0, end, price = 0;
        int i, j;
        int max = 0;
        while (sc.hasNext()) {
            start = sc.nextInt();
            end = sc.nextInt();
            price = sc.nextInt();
            for (i = start; i <= end; i++) {
                table[i] = price;
            }
            if (end > max)
                max = end;
        }

        boolean first=true;
        for (i = 0; i <= max; i++) {
            if (table[i] != 0) {
                start = i;
                while (i+1 <= max && table[i] == table[i + 1])
                    i++;
                if(first) {
                    System.out.printf("[%d, %d, %d]", start, i, table[i]);
                    first = false;
                } else System.out.printf(",[%d, %d, %d]", start, i, table[i]);
            }
        }
    }
}
发表于 2017-08-09 06:23:24 回复(4)