题目思路
1、输入数据的保存,并记录下被取消的交易
2、根据第一步,获取最终buy 和 sell 的交易记录,对记录按照价格升序排序
3、对buy 和 sell 中的记录各自求一下销售量的前缀和
3、双指针做法,i循环buy中的记录,j查找sell中符合条件的记录位置
4、更新一下在开盘价最大的情况下的一个交易量
疑问
1、我这边对于开盘价的选择只是从buy数据中获取的,然后找到sell中符合条件的位置,计算并更新
但是并不确定我们最后的开盘价一定是在buy中出现的,但是这样做直接就过了。。。。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main
{
private static int N=5010;
private static List<Node> list=new ArrayList<>();
private static boolean[] st=new boolean[N];//标记第几行记录取消了
private static List<Node> list1=new ArrayList<>();//买单
private static List<Node> list2=new ArrayList<>();//卖单
static Comparator<Node> cmp=new Comparator<Node>()
{
@Override
public int compare(Node o1, Node o2)
{
return o1.sortPrice-o2.sortPrice;
}
};
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
int cnt=0;
while(scan.hasNextLine())
{
String str=scan.nextLine();
if("".equals(str))
break;
cnt++;
String[] split = str.split("\\s+");
if("buy".equals(split[0]))
{
double price=Double.valueOf(split[1]);
long s =Long.valueOf(split[2]);
list.add(new Node("buy",price,s,cnt));
}
else if("sell".equals(split[0]))
{
double price=Double.valueOf(split[1]);
long s =Long.valueOf(split[2]);
list.add(new Node("sell",price,s,cnt));
}
if("cancel".equals(split[0]))
{
int t=Integer.valueOf(split[1]);
st[t]=true;//此行记录取消
}
}
for(int i=0;i<list.size();i++)
{
Node t=list.get(i);
if(t.type.equals("buy")&&!st[t.sort])
list1.add(t);
else if(t.type.equals("sell")&&!st[t.sort])
list2.add(t);
}
Collections.sort(list1,cmp);
Collections.sort(list2,cmp);
// for(int i=0;i<list1.size();i++)
// System.out.println(list1.get(i).price);
// System.out.println();
// for(int i=0;i<list2.size();i++)
// System.out.println(list2.get(i).price);
//求前缀和
for(int i=1;i<list1.size()&&list1.size()>1;i++)
list1.get(i).s+=list1.get(i-1).s;
for(int i=1;i<list2.size()&&list2.size()>1;i++)
list2.get(i).s+=list2.get(i-1).s;
double ansPri=0;
long ansCnt=Long.MIN_VALUE;
//双指针做法
for(int i=0,j=-1;i<list1.size();i++)
{
long t1=0;//买单 卖单各自的成交量
double tempri=list1.get(i).price;
while(j+1<list2.size()&&list2.get(j+1).price<=tempri)
j++;
if(j!=-1)
{
//各自成交量取最小值
if(i==0)
{
t1=list1.get(list1.size()-1).s;
}
else
t1=list1.get(list1.size()-1).s-list1.get(i-1).s;
t1=Math.min(t1,list2.get(j).s);
if(t1>ansCnt)
{
ansCnt=t1;
ansPri=tempri;
}
else if(t1==ansCnt)
{
ansPri=Math.max(ansPri, tempri);
}
}
}
System.out.printf("%.2f",ansPri);
System.out.println(" "+ansCnt);
scan.close();
}
private static class Node
{
private String type;
private double price;
private long s;
private int sort;
private int sortPrice;
public Node(String type, double price, long s,int sort)
{
super();
this.type = type;
this.price = price;
this.s = s;
this.sort=sort;
this.sortPrice=(int)(this.price*100);
}
}
}