最近希望在日常加強一下算法的水平,所以找了一個ACM網站來強行刷水題,不過腦子笨,刷個題老半天的,果然技術有限啊,先做個最簡單的會場安排問題來增強一下自信心吧。
描述
學校的小禮堂每天都會有許多活動,有時間這些活動的計劃時間會發生沖突,需要選擇出一些活動進行舉辦。小劉的工作就是安排學校小禮堂的活動,每個時間最多安排一個活動?,F在小劉有一些活動計劃的時間表,他想盡可能的安排更多的活動,請問他該如何安排。
輸入
第一行是一個整型數m(m<100)表示共有m組測試數據。
每組測試數據的第一行是一個整數n(1<n<10000)表示該測試數據共有n個活動。
隨后的n行,每行有兩個正整數Bi,Ei(0<=Bi,Ei<10000),分別表示第i個活動的起始與結束時間(Bi<=Ei)
輸出
對于每一組輸入,輸出最多能夠安排的活動數量。
每組的輸出占一行
注意:如果上一個活動在t時間結束,下一個活動最早應該在t+1時間開始
我們直接來考慮算法部分的問題吧,如果從一組活動數據中算出會場安排的最優解,我們需要好好的分析問題,抽取問題的實質才行。比如這個會場安排問題,怎么才能矩形盡可能多的活動呢?自然是活動的時間盡可能短,并且不同的活動能夠進行銜接,那么舉辦的活動數量就最多的了。比如下面的
首先能夠銜接的會議必定是下一個活動的開始時間必定是大于上一個活動的結束時間,而下一個活動的結束時間必定是大于上一個活動的結束時間的,如果存在兩個活動互斥,但是都能夠跟下一個活動銜接,那么我們就不需要考慮這些互斥的活動了,可以把這些互斥的活動算作一個單位。
假如存在一個更小的活動,可以跟這些互斥的活動中的一個或兩個銜接,那么這個更小的活動的結束時間必然都小于互斥活動的開始時間和結束時間,又因為這些活動的數據輸入時是無序的,所以首先要做的就是對所有活動進行排序。
private static int meeting_problem(int[] startTime,int[] endTime){
//一組活動數據的最優解
int maxresult = 1;
//冒泡排序,對startTime和endTime數據進行排序
for (int i = 0; i < endTime.length-1; i++) {
boolean canBreak = true;
for (int j = 1; j < endTime.length - i; j++) {
if (endTime[j-1] > endTime[j]) {
int temp = endTime[j - 1];
endTime[j-1] = endTime[j];
endTime[j] = temp;
int temp2 = startTime[j - 1];
startTime[j-1] = startTime[j];
startTime[j] = temp2;
canBreak = false;
}
}
if (canBreak) {
break;
}
}
// 記錄上一次活動的結束時間
int key = endTime[0];
for (int i = 1; i < endTime.length; i++) {
// 如果活動的開始時間能夠大于上一次活動的結束時間
if (startTime[i] - key >= 1){
//計數+1
maxresult ++;
//保存結束時間
key = endTime[i];
}
}
return maxresult;
}
上面就是獲取一組活動數據的最優解,結合輸入數據的代碼
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int[] results = new int[num];
for (int i = 0; i < num; i++) {
int a = scanner.nextInt();
int[] startTimes = new int[a];
int[] endTimes = new int[a];
for (int j = 0; j < a; j++) {
startTimes[j] = scanner.nextInt();
endTimes[j] = scanner.nextInt();
}
results[i] = (meeting_problem(startTimes, endTimes));
}
for (Integer result:results) {
System.out.println(result);
}
}
最后當然是通過了ACM的編譯了,可是發現了一個很嚴肅的問題,我不清楚是我的實現上有問題,還是Java和C++之間有這么大的效率差距
所以說刷水題還是用C/C++好一點,順道把C++撿回來也好,畢竟C++可以做Cocos-2d,而且安卓底層也需要用到c的基礎,總是好處很多的。
非常的尷尬,本來想用C++實現一次的,但是自己跑的時候能跑通,放上ACM就出錯了,不知道哪里出了問題。。。
#include<iostream>
#include <algorithm>
using namespace std;
struct active
{
int begin;
int end;
};
bool cmp(active x,active y)
{
return x.end<y.end;
}
int schedule(active* actives,int s,int e)
{
int n=0;
int i=s+1;
if (actives[s].begin > -1){
n=1;
for(;i<=e;i++)
if(actives[i].begin- actives[s].end >= 1){
s=i;
n++;
}
}
return n;
}
int main( )
{
int n,group;
cin>>n;
int *result = new int[n];
for(int j=0;j<n;j++){
cin>>group;
active *st= new active[group];
for(int i=0;i<group;i++)
cin>>st[i].begin>>st[i].end;
sort(st,st+group,cmp);
result[j] = schedule(st,0,group-1);
delete []st;
}
for(int i= 0;i<n;i++)
cout<< result[i] <<endl;
delete []result;
return 0;
}
或者使用C++效率更高也未可知吧。。。好久不用的C++撿回來也是夠嗆