import java.util.*;
public class BuildingOutline {
public static class Op{
public int x;
public boolean isAdd;//true为+
public int h;
public Op(int x,boolean isAdd,int h)
{
this.x = x;
this.isAdd = isAdd;
this.h = h;
}
}
public static class NodeComparator implements Comparator<Op>{
@Override
public int compare(Op o1, Op o2) {
if(o1.x != o2.x){
return o1.x - o2.x;
}
if(o1.isAdd != o2.isAdd){
return o1.isAdd ? -1:1;
}
return 0;
}
}
public static List<List<Integer>> buildOutlin(int[][] matrix){
int N = matrix.length;
Op[] ops= new Op[matrix.length * 2];
for (int i = 0; i < matrix.length; i++) {
ops[i*2] = new Op(matrix[i][0],true,matrix[i][2]);
ops[i*2+1] = new Op(matrix[i][1],false,matrix[i][2]);
}
Arrays.sort(ops,new NodeComparator());
// 这个有序表可以选出最高的高度,
TreeMap<Integer,Integer> mapHeightTimes = new TreeMap<>();
//x左边从小到大收集
TreeMap<Integer,Integer> mapXHeight = new TreeMap<>();
for (int i = 0; i < ops.length; i++) {
if(ops[i].isAdd){//高度加的优先操作,防止单个纸片,[3,3,2]
if(!mapHeightTimes.containsKey(ops[i].h)){
mapHeightTimes.put(ops[i].h,1);
}else{
mapHeightTimes.put(ops[i].h,mapHeightTimes.get(ops[i].h)+1);
}
}else{
if(mapHeightTimes.get(ops[i].h) == 1){
mapHeightTimes.remove(ops[i].h);
}else{
mapHeightTimes.put(ops[i].h,mapHeightTimes.get(ops[i].h)-1);
}
}
if(mapHeightTimes.isEmpty()){
mapXHeight.put(ops[i].x,0);
}else{
mapXHeight.put(ops[i].x,mapHeightTimes.lastKey());
}
}
List<List<Integer>> res = new ArrayList<>();
int start = 0;
int preHeight = 0;
for(Map.Entry<Integer,Integer> entry:mapXHeight.entrySet()){
int curX = entry.getKey();
int curMaxHeight = entry.getValue();
if(preHeight != curMaxHeight){
if(preHeight != 0){
res.add(new ArrayList<>(Arrays.asList(start,curX,preHeight)));
}
start = curX;
preHeight = curMaxHeight;
}
}
return res;
}
}
一个异或和不等于0的 先手赢,先手总能拿一个使得后手异或和等于0
import java.util.Arrays;
public class MinBoat {
public static int minBoat(int[] arr, int limit){
if(arr == null || arr.length == 0){
return 0;
}
Arrays.sort(arr);
if(arr[arr.length - 1] > limit){
return -1;
}
int lessR = -1;
for(int i = arr.length-1;i >= 0;i--){
if(arr[i] <=(limit/2)){
lessR = i;
break;
}
}
if(lessR == -1){
return arr.length;
}
//从中间划分
int L = lessR;//中间左边的指针
int R = lessR + 1;//中间右边的指针
int noUsed= 0; //画x的统计数量
while(L >= 0){
//同时防止右边提前使用完了
int sloved = 0;//此时的L,让R画了几个数
while (R < arr.length && arr[L] + arr[R] <= limit){
R++;
sloved++;
}
//上述完之后 R到了第一个不达标的位置
if(sloved == 0){
noUsed++;//X的个数增加
L--;
}else{
L = Math.max(-1,L-sloved);//L来到对应解决过的位置
}
}
int lessUsed = lessR + 1 - noUsed;//画对号的数量
int moreUnsolved = arr.length - lessR -1 - lessUsed;//>limt/2没有搞定的数量
//(N+1)/2 相当于N/2向上取整 因为如果还剩下一个人也要坐船
return lessUsed + (((noUsed)+1)>>1) + moreUnsolved;
}
}