CSP201412_3(集合競價)(Java100分)
阿新 • • 發佈:2018-11-22
問題描述
某股票交易所請你編寫一個程式,根據開盤前客戶提交的訂單來確定某特定股票的開盤價和開盤成交量。
該程式的輸入由很多行構成,每一行為一條記錄,記錄可能有以下幾種:
1. buy p s 表示一個購買股票的買單,每手出價為p,購買股數為s。
2. sell p s 表示一個出售股票的賣單,每手出價為p,出售股數為s。
3. cancel i表示撤銷第i行的記錄。
如果開盤價為p0,則系統可以將所有出價至少為p0的買單和所有出價至多為p0的賣單進行匹配。因此,此時的開盤成交量為出價至少為p0的買單的總股數和所有出價至多為p0的賣單的總股數之間的較小值。
你的程式需要確定一個開盤價,使得開盤成交量儘可能地大。如果有多個符合條件的開盤價,你的程式應當輸出最高的那一個。
輸入格式
輸入資料有任意多行,每一行是一條記錄。保證輸入合法。股數為不超過108的正整數,出價為精確到恰好小數點後兩位的正實數,且不超過10000.00。
輸出格式
你需要輸出一行,包含兩個數,以一個空格分隔。第一個數是開盤價,第二個是此開盤價下的成交量。開盤價需要精確到小數點後恰好兩位。
樣例輸入
buy 9.25 100
buy 8.88 175
sell 9.00 1000
buy 9.00 400
sell 8.92 400
cancel 1
buy 100.00 50
樣例輸出
9.00 450
評測用例規模與約定
對於100%的資料,輸入的行數不超過5000。
思路:先寫一個股票類。然後一個buy陣列和一個sell陣列。 另外需要一個boolean 型別的陣列。
輸入資料時有人可能遇到過使用hasNextLine()程式一直等待,無法結束的情況
while (sc.hasNextLine()) {
String s = sc.nextLine();
if (s.trim().length() == 0) {
break;
}
}
我也不知道為什麼這樣就可以。
然後就是對buy陣列和sell陣列重小到大排序。
如果開盤價為x時,計算 開盤成交量為出價至少為p0的買單的總股數和所有出價至多為p0的賣單的總股數之間的較小值。 然後和結果比較 。然後如果這個大,就替換掉結果。。說的可能有點亂,你們直接看程式碼吧。
另一個我遇到的bug就是實現Comparable介面時,沒有寫價格相等的時候,返回0
if (price < o.price) {
return -1;
} else {
return 1;
}
}
執行時只有80分,提示執行錯誤。
最後改成:
public int compareTo(Stock o) {
// TODO Auto-generated method stub
if (price < o.price) {
return -1;
} else if (price == o.price) {
return 0;
} else {
return 1;
}
}
然後就100分了。
這個原因就是如果輸入的價格都相等的時候 ,無法排序,然後丟擲異常造成的。
下面是程式碼:
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// new BufferedInputStream(
int num = 1;
boolean isCancel[] = new boolean[5005];
for (int i = 0; i < isCancel.length; i++) {
isCancel[i] = false;
}
Stock buy[] = new Stock[5005];
Stock sell[] = new Stock[5005];
int buyNum = 0;
int sellNum = 0;
while (sc.hasNextLine()) {
String s = sc.nextLine();
if (s.trim().length() == 0) {
break;
}
if (s.contains("buy")) {
buy[buyNum++] = new Stock(num++, Float.parseFloat(s.split(" ")[1]), Long.parseLong(s.split(" ")[2]));
} else if (s.contains("sell")) {
sell[sellNum++] = new Stock(num++, Float.parseFloat(s.split(" ")[1]), Long.parseLong(s.split(" ")[2]));
} else if (s.contains("cancel")) {
isCancel[Integer.parseInt(s.split(" ")[1])] = true;
num++;
}
}
Arrays.sort(buy, 0, buyNum);
Arrays.sort(sell, 0, sellNum);
int indexBuy = buyNum - 1;
float resultPrice = 0;
long resultNum = 0;
long tempNumBuy = 0;
while (indexBuy >= 0) {
if (!isCancel[buy[indexBuy].id]) {
float tempPrice = buy[indexBuy].price;
tempNumBuy += buy[indexBuy].num;
long tempNumSell = 0;
for (int i = 0; i < sellNum; i++) {
if ((!isCancel[sell[i].id]) && sell[i].price <= tempPrice) {
tempNumSell += sell[i].num;
}
}
long tempResultNum = Math.min(tempNumBuy, tempNumSell);
if (tempResultNum > resultNum) {
resultPrice = tempPrice;
resultNum = tempResultNum;
}
} else {
}
indexBuy--;
}
System.out.printf("%5.2f ", resultPrice);
System.out.println(resultNum);
}
}
class Stock implements Comparable<Stock> {
int id;
float price;
long num;
public Stock(int id, float price, long num) {
super();
this.id = id;
this.price = price;
this.num = num;
}
@Override
public int compareTo(Stock o) {
// TODO Auto-generated method stub
if (price < o.price) {
return -1;
} else if (price == o.price) {
return 0;
} else {
return 1;
}
}
@Override
public String toString() {
// TODO Auto-generated method stub
return " id:" + id + " price:" + price + " num:" + num;
}
}