//裝箱問題的簡單實現
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef struct{
int gno;
int gv;
}Goods;
class GNode{
private:
int gno;
GNode * link = NULL;
public:
GNode(int gno){
this->gno = gno;
}
~GNode(void){}
int &Getgno(){return gno;}
GNode* &Getlink(){return link;}
};
class GBox{
private:
int gv = 10;
GNode *gh = NULL;
GBox *next = NULL;
public:
GBox(void){}
~GBox(void){}
int &Getgv(){return gv;}
GNode* &Getgh(){return gh;}
GBox* &Getnext(){return next;}
};
class Realize{
private:
GBox *ghead = NULL;
Goods *goods = NULL;
int n;
public:
Realize(int value):n(value){}
~Realize(){}
void goodsinit(void);
void PackingBox();
void PrintTable();
void PrintResult();
void dofun(void);
};
void Realize::goodsinit(void){
srand((unsigned)time(NULL));
goods = new Goods[n]();
for(int i=0;i<n;i++){
goods[i].gno = i+1;
goods[i].gv = rand()%10+1;
}
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++){
Goods t;
if(goods[i].gv < goods[j].gv){
t = goods[i];
goods[i] = goods[j];
goods[j] = t;
}
}
}
void Realize::PrintTable(){
for(int i=0;i<n;i++){
cout<<"NO."<<goods[i].gno<<":"<<goods[i].gv<<endl;
}
}
void Realize::PackingBox(){
GNode *j;
GBox *p,*t = NULL;
for(int i=0;i<n;i++){
j = new GNode(goods[i].gno);
p = ghead;
//找到第一個可以放的箱子或者是新開一個箱子
while(p && p->Getgv() < goods[i].gv){
p = p->Getnext();
}
if(!p){//p爲空,開新箱子
if(!t){//頭結點
p = ghead = t = new GBox();
}
else{
p = t = t->Getnext() = new GBox();
}
}
//p可以被放在當前位置
if(!p->Getgh()){//箱子裏無物品
p->Getgh() = j;
}
else{
GNode *k = p->Getgh();
while(k->Getlink())
k = k->Getlink();
k->Getlink() = j;
}
p->Getgv() -= goods[i].gv;
}
}
void Realize::PrintResult(void){
GBox *p;
GNode *q;
int i = 1;
for(p = ghead;p;p = p->Getnext()){
cout<<"第"<<i++<<"個箱子:"<<endl;
for(q = p->Getgh();q;q = q->Getlink()){
cout<<"NO."<<q->Getgno()<<" ";
}
cout<<"剩餘空間:"<<p->Getgv()<<endl;
}
}
void Realize::dofun(void){
goodsinit();
PrintTable();
cout<<"物品清單排序完畢!"<<endl;
PackingBox();
cout<<"裝箱完畢!"<<endl;
PrintResult();
cout<<"輸出結果完畢!"<<endl;
}
int main(void)
{
Realize* r = new Realize(20);
r->dofun();
return 0;
}