輸入文件:student.txt distance.txtios
你是小學某班主任,須要安排週六進行家訪。因而打電話與家長聯繫,他們表示雖然比較忙,但仍是會爲你抽出一點時間。因爲有些家長時間上有衝突,而且一天內不能拜訪全部家長,你須要一個程序安排一天的工做,使得你能夠拜訪最多的家長。注意, 若是與某個家長見面,拜訪時間不得少於45分鐘(M),不然可能引發家長不滿意。另外從一個家長到另一個家長鬚要花費一些時間。測試
Input1: student.txtthis
輸入包括多個測試數據,每一個測試數據開頭是一個整數n(1<=n<=40),表示家長總數。接下來n行每行包括三個正整數m、s、t。m表示家長的序號,s、t分別表示該家長空閒時間段的起始時間和終止時間,s小於t。注意兩個數字的最後兩位表示分鐘。好比1645 表示16時45分。樣本以下:spa
6code
1 800 1100 orm
2 800 900ci
3 845 1000element
4 1300 1400get
5 1345 1800it
6 1500 1700
Input2: distance.txt
第一行爲 家長總數隨後爲一個二維表格,記錄每2個用戶之間的距離。第二行和第一列數據爲家長順序編號。其餘數據爲2個家長之間的距離。樣本以下:
6
0 1 2 3 4 5 6
1 0 1 2 4 3 1
2 1 0 3 5 3 2
3 2 3 0 6 1 3
4 4 5 6 0 4 14
5 3 3 1 4 0 15
6 1 2 3 14 15 0
Output:
拜訪的家長總數
拜訪的家長的序號和開始結束時間
我獲得的結果爲(時間按照分鐘計算):
因爲預賽時間尚未結束,故不能將代碼公佈,有興趣的朋友能夠想一想。
現將代碼公佈以下(2010-08-11):
/***************************************************************************** * constants.h * * Some constants. * * Zhang Ming, 2010-05 *****************************************************************************/ #ifndef CONSTANTS_H #define CONSTANTS_H #include <climits> const int INFTY = INT_MAX; const int VISITTIME = 45; const int INITSIZE = 20; const int EXTFACTOR = 2; #endif // CONSTANTS_H
#ifndef ALLOCATE_2D_MATRIX_H_ #define ALLOCATE_2D_MATRIX_H_ template<typename Type> inline void make2DArray(Type **&x,int rows,int cols) { x = new Type*[rows]; for(int i = 0; i < rows; ++i) x[i] = new Type[cols]; } template<typename Type> inline void delete2DArray(Type**& x,int rows) { for(int i = 0; i < rows; ++i) delete [] x[i]; delete [] x; x = 0; } #endif // ALLOCATE_2D_MATRIX_H_
/***************************************************************************** * stack.h * * Stack class. * * Zhang Ming, 2010-05 *****************************************************************************/ #ifndef STACK_H #define STACK_H #include <iostream> #include <cstdlib> #include "constants.h" using namespace std; template <typename Type> class Stack { public: explicit Stack( int maxSize = INITSIZE ); Stack( const Stack<Type> &s ); ~Stack(); Stack<Type>& operator=( const Stack<Type> &s ); inline bool isEmpty() const; inline void push( const Type &x ); inline Type pop(); private: int top; int capacity; Type *elements; void handleOverflow(); }; // class Stack /** * constructors and destructor */ template <typename Type> Stack<Type>::Stack( int maxSize ) : top (-1), capacity(maxSize) { elements = new Type[maxSize]; if( !elements ) { cerr << "Out of memory!" << endl; exit(1); } }; template <typename Type> Stack<Type>::Stack( const Stack<Type> &s ) { top = s.top; capacity = s.capacity; elements = new Type[capacity]; for( int i=0; i<=top; ++i ) elements[i] = s.elements[i]; } template <typename Type> Stack<Type>::~Stack() { top = -1; capacity = INITSIZE; delete []elements; } /** * Overload copy assignment operation. */ template <typename Type> Stack<Type>& Stack<Type>::operator=( const Stack<Type> &s ) { top = s.top; capacity = s.capacity; elements = new Type[capacity]; for( int i=0; i<=top; ++i ) elements[i] = s.elements[i]; return *this; } /** * If the stack is empty, return true. */ template <typename Type> inline bool Stack<Type>::isEmpty() const { return ( top == -1 ); } /** * Push an element into the stack. */ template <typename Type> inline void Stack<Type>::push( const Type &x ) { elements[++top] = x; if( top == capacity-1 ) handleOverflow(); }; /** * Pop an element out of stack. */ template <typename Type> inline Type Stack<Type>::pop() { if( !isEmpty() ) return elements[top--]; else { cerr << "The stack is empty!" << endl << endl; return Type(); } }; /** * If the capability of the stack exceeds the initial size, * make it double. */ template <typename Type> void Stack<Type>::handleOverflow() { capacity = EXTFACTOR * capacity ; Type *newArray = new Type[capacity]; if( newArray == NULL ) { cerr << "Out of memory!" << endl; exit(1); } for( int i=0; i<=top; ++i ) newArray[i] = elements[i]; delete []elements; elements = newArray; }; #endif // STACK_H
/***************************************************************************** * binaryheap.h * * Minimum binary heap class. * * Zhang Ming, 2010-05 *****************************************************************************/ #ifndef BINARYHEAP_H #define BINARYHEAP_H #include <iostream> #include <cstdlib> #include "constants.h" using namespace std; template <typename Type> class BinaryHeap { public: explicit BinaryHeap( int maxSize = INITSIZE ); BinaryHeap( const BinaryHeap<Type> &h ); BinaryHeap( Type *array, int length ); ~BinaryHeap(); BinaryHeap<Type>& operator=( const BinaryHeap<Type> &h ); inline bool isEmpty() const; inline void deleteMin( Type &minItem ); inline void adjust(); inline int getSize() const; inline Type* getEntries() const; private: Type *elements; int currentSize; int capacity; void filterDown( int hole ); void filterUp( int hole ); void handleOverflow(); }; // class BinaryHeap /** * constructors and destructor */ template <typename Type> BinaryHeap<Type>::BinaryHeap( int maxSize ) { capacity = maxSize; elements = new Type[capacity+1]; if( elements == NULL ) cerr << "Out of memory!" << endl; currentSize = 0; } template <typename Type> BinaryHeap<Type>::BinaryHeap( Type *array, int length ) { capacity = ( INITSIZE > length ) ? INITSIZE : length; elements = new Type[capacity+1]; if( elements == NULL ) cerr << "Out of memory!" << endl; for( int i=0; i<length; ++i ) elements[i+1] = array[i]; currentSize = length; for( int i=currentSize/2; i>0; --i ) filterDown( i ); } template <typename Type> BinaryHeap<Type>::BinaryHeap( const BinaryHeap<Type> &h ) { currentSize = h.currentSize; capacity = h.capacity; elements = new Type[capacity]; for( int i=1; i<=currentSize; ++i ) elements[i] = h.elements[i]; } template <typename Type> BinaryHeap<Type>::~BinaryHeap() { currentSize = 0; capacity = INITSIZE; delete []elements; } /** * Overload copy assignment operation. */ template <typename Type> BinaryHeap<Type>& BinaryHeap<Type>::operator=( const BinaryHeap<Type> &h ) { currentSize = h.currentSize; capacity = h.capacity; elements = new Type[capacity]; for( int i=1; i<=currentSize; ++i ) elements[i] = h.elements[i]; return *this; } /** * If the heap is empty, return true. */ template <typename Type> inline bool BinaryHeap<Type>::isEmpty() const { return currentSize == 0; } /** * Remove the minimum item and place it in minItem. */ template <typename Type> inline void BinaryHeap<Type>::deleteMin( Type &minItem ) { if( !isEmpty() ) { minItem = elements[1]; elements[1] = elements[currentSize--]; filterDown( 1 ); } else cerr << "The heap is empty!" << endl << endl; } /** * Adjust the array to be a heap. */ template <typename Type> inline void BinaryHeap<Type>::adjust() { for( int i=currentSize/2; i>0; --i ) filterDown(i); } /** * Get current size of the heap. */ template <typename Type> inline int BinaryHeap<Type>::getSize() const { return currentSize; } /** * Get the element pointer of the heap. */ template <typename Type> inline Type* BinaryHeap<Type>::getEntries() const { return elements; } /** * Percolate down the heap, begin at "hole". */ template <typename Type> void BinaryHeap<Type>::filterDown( int hole ) { int child; Type tmp = elements[hole]; for( ; 2*hole<=currentSize; hole=child ) { child = 2*hole; if( child != currentSize && elements[child+1] < elements[child] ) child++; if( elements[child] < tmp ) elements[hole] = elements[child]; else break; } elements[hole] = tmp; } /** * Percolate up the heap, begin at "hole". */ template <typename Type> void BinaryHeap<Type>::filterUp( int hole ) { Type tmp = elements[hole]; for( ; hole>1 && tmp<elements[hole/2]; hole/=2 ) elements[hole] = elements[hole/2]; elements[hole] = tmp; } /** * If the capability of the heap exceeds the initial size, make it double. */ template <typename Type> void BinaryHeap<Type>::handleOverflow() { capacity = EXTFACTOR * capacity; Type *newArray = new Type[capacity+1]; if( newArray == NULL ) { cerr << "Out of memory!" << endl; exit(1); } for( int i=1; i<=currentSize; ++i ) newArray[i] = elements[i]; delete []elements; elements = newArray; }; #endif // BINARYHEAP_H
/***************************************************************************** * student.h * * The student class with comparison operators. * * Zhang Ming, 2010-05 *****************************************************************************/ #ifndef STUDENT_H #define STUDENT_H #include <iostream> #include "constants.h" using namespace std; class Student { public: int number; int key; int stopTime; Student() : number(0), key(0), stopTime(0) { } Student( int num, int k, int stop ) { number = num; key = k; stopTime = stop; } ~Student() {} void operator=( const Student &stu ) { number = stu.number; key = stu.key; stopTime = stu.stopTime; } inline bool operator==( const Student &stu ) { return key == stu.key; } inline bool operator<( const Student &stu ) { if( key == stu.key ) return stopTime < stu.stopTime; else return key < stu.key; } inline bool satisfy() { return stopTime-key >= 45; } friend ostream& operator<<( ostream &out, Student &stu ) { out << stu.number << " " << stu.key << " " << stu.stopTime << endl; return out; } }; // struct Student #endif // STUDENT_H
#ifndef FLOYD_SHORTEST_PASH_H_ #define FLOYD_SHORTEST_PASH_H_ #include <cstdlib> #include "constants.h" template <typename Type> void floyd(Type **shortestDist, Type **directDist, int n, int **path) { int i=0, j=0, k=0; for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { shortestDist[i][j] = directDist[i][j]; if (i!=j && directDist[i][j]<INFTY) { path[i][j] = i; } else path[i][j] = -1; } } for (k=0; k<n; ++k) { for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { if (shortestDist[i][k]+shortestDist[k][j] < shortestDist[i][j]) { shortestDist[i][j] = shortestDist[i][k]+shortestDist[k][j]; path[i][j] = path[k][j]; } } } } } template <typename Type> void floyd(Type **shortestDist, Type **directDist, int n) { int i=0, j=0, k=0; for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { shortestDist[i][j] = directDist[i][j]; } } for (k=0; k<n; ++k) { for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { if (shortestDist[i][k]+shortestDist[k][j] < shortestDist[i][j]) { shortestDist[i][j] = shortestDist[i][k]+shortestDist[k][j]; } } } } } template <typename Type> void floyd(Type **dist, int n) { int i=0, j=0, k=0; for (k=0; k<n; ++k) { for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { if (dist[i][k]+dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k]+dist[k][j]; } } } } } #endif // FLOYD_SHORTEST_PASH_H_
/***************************************************************************** * visit.h * * Find the visit routine. * * Zhang Ming, 2010-05 *****************************************************************************/ #ifndef VISIT_H #define VISIT_H #include "student.h" #include "stack.h" #include "binaryheap.h" int visit( BinaryHeap<Student> &h, Stack<Student> &s, int **dist ) { if( h.isEmpty() ) return 0; Student stu, tmp; h.deleteMin(stu); if( !stu.satisfy() ) return visit( h, s, dist ); int newStart, thisNum, curSize = h.getSize(); if( curSize > 0 ) { Stack<Student> ss(curSize); Stack< BinaryHeap<Student> > hs(curSize); Student *p = h.getEntries(); Student *q = new Student[curSize]; for( int i=1; i<=curSize; ++i ) { newStart = stu.key + VISITTIME + dist[stu.number-1][p[i].number-1]; if( newStart > p[i].key ) { ss.push(p[i]); tmp = p[i]; for( int j=1; j<=curSize; ++j ) q[j-1] = p[j]; q[i-1] = stu; for( int j=0; j<curSize; ++j ) { newStart = tmp.key + VISITTIME + dist[tmp.number-1][q[j].number-1]; if( newStart > q[j].key ) q[j].key = newStart; } hs.push( BinaryHeap<Student>(q,curSize) ); } } for( int i=1; i<=curSize; ++i ) { newStart = stu.key + VISITTIME + dist[stu.number-1][p[i].number-1]; if( newStart > p[i].key ) p[i].key = newStart; } h.adjust(); thisNum = visit( h, s, dist ); while( !hs.isEmpty() ) { Stack<Student> os(curSize); BinaryHeap<Student> oh = hs.pop(); int otherNum = visit( oh, os, dist ); if( otherNum > thisNum ) { s = os; thisNum = otherNum; stu = ss.pop(); } else ss.pop(); } } else thisNum = 0; stu.stopTime = stu.key + VISITTIME; s.push(stu); return thisNum + 1; } #endif // VISIT_H
#ifndef FILE_READER_H_ #define FILE_READER_H_ void read2Files(char *stuFile, char* distFile, int **&info, int **&dist, int &n); void printMatrix(int **matrix, int row, int col=-1); #endif // FILE_READER_H_
#include "fileReader.h" #include "matrixAllocate.h" #include <cstdio> #include <conio.h> #include <cstdlib> void read2Files(char *stuFile, char* distFile, int **&info, int **&dist, int &n) { FILE *fp = fopen(stuFile, "rt"); int id, s, t, hour, minute; int i, j; if(fp) { fscanf(fp, "%d", &n); make2DArray(info, n, 3); for(i = 0; i < n; i++) { fscanf(fp, "%d%d%d", &id, &s, &t); info[i][0] = id; hour = s / 100; minute = s % 100; s = hour * 60 + minute; info[i][1] = s; hour = t / 100; minute = t % 100; t = hour * 60 + minute; info[i][2] = t; } } else { printf("Can't open file: \"%s\"!\n", stuFile); exit(1); } int r, temp; FILE *fpd = fopen(distFile, "rt"); if(fpd) { fscanf(fpd, "%d", &r); if(r != n) { printf("\"%s\" and \"%s\" have diffierent row number!\n", stuFile, distFile); exit(1); } make2DArray(dist, r, r); //fseek(fp, 7, 1); for(i = 0; i <= r; i++) fscanf(fpd, "%d", &temp); for(i = 0; i < r; i++) { fscanf(fpd, "%d", &temp); for(j = 0; j < r; j++) { fscanf(fpd, "%d", &dist[i][j]); } } } else { printf("Can't open file: \"%s\"!\n", distFile); exit(1); } } void printMatrix( int **matrix, int row, int col ) { for(int i = 0; i < row; ++i) { for(int j = 0; j < col; ++j) { printf("%5d", matrix[i][j]); } printf("\n"); } printf("\n"); }
/***************************************************************************** * visit_test.cpp * * Visiting testing. * * Zhang Ming, 2010-05 *****************************************************************************/ #include <iostream> #include "matrixAllocate.h" #include "fileReader.h" #include "floyd.h" #include "visit.h" using namespace std; int main() { int n, totNum = 0; int **time = 0; // n * 3 int **dist = 0; // n * n int **shortestDist = 0;// n * n int **path = 0;// n * n char *fileName1 = (char*) "student.txt"; char *fileName2 = (char*) "distance.txt"; read2Files( fileName1, fileName2, time, dist, n ); cout << "The visiting time information: " << endl; printMatrix( time, n, 3); cout << "The visiting distance information: " << endl; printMatrix( dist, n, n); make2DArray( shortestDist, n, n); make2DArray( path, n, n); floyd(dist, n); cout << "The shortest visiting distance information: " << endl; printMatrix(dist, n, n); Student x, *Stu = new Student[n]; for( int i=0; i<n; ++i ) { Stu[i].number = time[i][0]; Stu[i].key = time[i][1]; Stu[i].stopTime = time[i][2]; } Stack<Student> s(n); BinaryHeap<Student> heap( Stu, n ); totNum = visit( heap, s, dist ); cout << "The total number of visited students is: " << totNum << endl << endl; cout << "The visiting order and time information: " << endl; while( !s.isEmpty() ) { x = s.pop(); cout << " " << x; } cout << endl; return 0; }