魔獸世界之一:備戰

yjh1995725發表於2018-09-04

原題地址: http://cxsjsxmooc.openjudge.cn/2018t3springw3/5/

自己的程式碼:

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define Num 5//使用const int更好 

class Warror;
class Headqurater;//類的定義要寫在前面 
class Warror{
	private:
		Headqurater *h; //指向基地 
		int noWarror;//名字編號 
		int no;//編號 
	public:
		static string name[Num];//名稱陣列 
		static int life[Num];//生命值陣列 
		Warror( Headqurater *h1, int noWarror1, int no1);
		void print(int t);//列印出武士資訊 
};
class Headqurater{
	private:
		int power;//總能量值 
		int tolWarrors;//戰士總數量 
		Warror *warrors[10000];
		int rule[Num];
		bool stop;
	public:
		int color;
		int numWarrors[Num];
		void init( int color1, int power1, int rule1[], bool stop1);//初始化物件 
		int  produce( int t, int ptr);//生產武士 
		void print( int t);//不能生產列印 
		bool isEnd( );//改變狀態標誌
		//解構函式必須要有,可能存在多組資料   整個完成以後要釋放空間 
};
Warror::Warror( Headqurater *h1, int noWarror1, int no1){
	h = h1, noWarror = noWarror1, no = no1;
};

void Warror::print(int t){
	string color;
	if(h->color)  color = "red";
	else color = "blue";
	printf("%03d ", t);
	cout << color << " " << name[noWarror] << " " << no << " born with strength " << life[noWarror] << "," << h->numWarrors[noWarror] << " " << name[noWarror] << " in " << color << " headqurater" << endl;
	//printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n", t, color, name[noWarror], no, life[noWarror], h->numWarrors[noWarror], name[noWarror], color);
	//string 類在C語言中不存在,要避免使用printf函式 
};


void Headqurater::init(int color1, int power1, int rule1[], bool stop1){
	color = color1, power = power1, memcpy(rule,rule1,sizeof(int)*Num), stop = stop1;
	tolWarrors = 0;
	memset(numWarrors,0,sizeof(int)*Num);
};
void Headqurater::print( int t){
	printf("%03d",t);
	if(color) printf(" red");
	else printf(" blue");
	printf(" headquarter stops making warroriors\n");
	stop = true;
};
bool Headqurater::isEnd( ){
	if(stop) return true;
	else return false;
};
int  Headqurater::produce( int t, int ptr){
	if(stop) return 0;
	int a= rule[ptr % Num];
	if( power >= Warror::life[a]){
		tolWarrors++;
		numWarrors[a]++;
		Warror tmp(this, a, t+1);
		warrors[tolWarrors] = &tmp;
		power -= Warror::life[a];
		tmp.print(t);
		return 1;
	};
	if(power < Warror::life[a]) return -1;
};

string Warror::name[Num] = {"dragon", "ninga", "iceman", "lion", "wolf"};//靜態變數後面定義不需要加  static  
int  Warror::life[Num] = {0};
int rule1[Num] = {2, 3, 4 ,1, 0};
int rule2[Num] = {3, 0, 1, 2, 4};

int main(){
	int a, power;
	cin >> a ;
	int caseNo = 0;
	while(a--){
		caseNo++;
		cin >> power;
		for( int i = 0; i < Num; ++i) 
	    cin >> Warror::life[i];
	    Headqurater red, blue;
	    red.init(1, power, rule1, false);
	    blue.init(0, power, rule2, false);
		printf("Case : %d\n", caseNo);
		int ptrR = 0, ptrB = 0, t = 0, flagR = 0 , flagB = 0;//ptrR,ptrB為分別在紅藍基地中指向當前生產的武士,flagB,flagR為結束生產標誌 
		while( !red.isEnd( ) || !blue.isEnd( ) ){
			if( !red.isEnd()){
			 	int signR = red.produce(t, ptrR);
			 	while( signR != 1){
			   		ptrR++, flagR++;//向下一個位置移動 
			   		signR = red.produce(t, ptrR);
			   		if( flagR == 5) {//遍歷所有武士,均沒有能生產的  
			   			red.print(t); 
						break;
		       		};
		    	};
		    	if(signR == 1) {
		    		signR = 0;
		    		ptrR ++;
		        };
		    };
		    
		    if( !blue.isEnd( )){
		    	int signB = blue.produce(t, ptrB);
		    	while( signB != 1){
		    		ptrB++, flagB++;
		    		signB = red.produce(t, ptrB	);
		    		if( flagB == 5 ){
		    			blue.print(t);
		    			break;
		    		};
		    	};
		    	if( signB == 1) {
					signB = 0;
					ptrB ++;
		        };
		    };
		    t++;
		};
	};

		return 0;
};

老師的程式碼:

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
const int  WARRIOR_NUM = 5;
/*
string Warrior::names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
紅方司令部按照 iceman、lion、wolf、ninja、dragon 的順序製造武士。
藍方司令部按照 lion、dragon、ninja、iceman、wolf 的順序製造武士。
*/
 
class Headquarter;
class Warrior
{
	private:
		Headquarter * pHeadquarter;
		int kindNo; //武士的種類編號 0 dragon 1 ninja 2 iceman 3 lion 4 wolf
		int no;
	public:
		static string names[WARRIOR_NUM];
		static int initialLifeValue [WARRIOR_NUM];
		Warrior( Headquarter * p,int no_,int kindNo_ );
		void PrintResult(int nTime);
};
 
class Headquarter
{
	private:
		int totalLifeValue;
		bool stopped;
		int totalWarriorNum;
		int color;
		int curMakingSeqIdx; //當前要製造的武士是製造序列中的第幾個
		int warriorNum[WARRIOR_NUM]; //存放每種武士的數量
		Warrior * pWarriors[1000];
	public:
		friend class Warrior;//為啥要定義友元?   方便訪問私有成員 
		static int makingSeq[2][WARRIOR_NUM]; //武士的製作順序序列
		void Init(int color_, int lv);
		~Headquarter () ;
		int Produce(int nTime);
		string GetColor();
 
};
 
 
Warrior::Warrior( Headquarter * p,int no_,int kindNo_ ) {
	no = no_;
	kindNo = kindNo_;
	pHeadquarter = p;
}
 
void Warrior::PrintResult(int nTime)
{
    string color =  pHeadquarter->GetColor();
    printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n"	,
        nTime, color.c_str(), names[kindNo].c_str(), no, initialLifeValue[kindNo],
        pHeadquarter->warriorNum[kindNo],names[kindNo].c_str(),color.c_str());// string 在printf中輸出的函式呼叫c_str() 
}
 
void Headquarter::Init(int color_, int lv)
{
	color = color_;
	totalLifeValue = lv;
	totalWarriorNum = 0;
	stopped = false;
	curMakingSeqIdx = 0;
	for( int i = 0;i < WARRIOR_NUM;i++ )
		warriorNum[i] = 0;
}
 
Headquarter::~Headquarter () {
	for( int i = 0;i < totalWarriorNum;i++ )
		delete pWarriors[i];
}
 
int Headquarter::Produce(int nTime)
{
 
	if( stopped )
		return 0;
	int searchingTimes = 0;
	while( Warrior::initialLifeValue[makingSeq[color][curMakingSeqIdx]] > totalLifeValue &&
		searchingTimes < WARRIOR_NUM ) {
		curMakingSeqIdx = ( curMakingSeqIdx + 1 ) % WARRIOR_NUM;
		searchingTimes++;
	}
	int kindNo = makingSeq[color][curMakingSeqIdx];
	if( Warrior::initialLifeValue[kindNo] > totalLifeValue ) {
		stopped = true;
		if( color == 0)
			printf("%03d red headquarter stops making warriors\n",nTime);
		else
			printf("%03d blue headquarter stops making warriors\n",nTime);
		return 0;
	}
	//製作士兵:
	totalLifeValue -= Warrior::initialLifeValue[kindNo];
	curMakingSeqIdx = ( curMakingSeqIdx + 1 ) % WARRIOR_NUM;
	pWarriors[totalWarriorNum] = new Warrior( this,totalWarriorNum+1,kindNo);
	warriorNum[kindNo]++;
	pWarriors[totalWarriorNum]->PrintResult(nTime);
	totalWarriorNum++;
	return 1;
}
 
string Headquarter::GetColor()
{
	if( color == 0)
		return "red";
	else
		return "blue";
}
 
string Warrior::names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int Warrior::initialLifeValue [WARRIOR_NUM];
int Headquarter::makingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} }; //兩個司令部武士的製作順序序列
 
int main()
{
	int t;
	int m;
	Headquarter RedHead,BlueHead;
	scanf("%d",&t);
	int nCaseNo = 1;
	while ( t-- ) {
		printf("Case:%d\n",nCaseNo++);
		scanf("%d",&m);
		for( int i = 0;i < WARRIOR_NUM;i++ )
		scanf("%d", & Warrior::initialLifeValue[i]);
		RedHead.Init(0,m);
		BlueHead.Init(1,m);
		int nTime = 0;
		while(true) {
			int tmp1 = RedHead.Produce(nTime);
			int tmp2 = BlueHead.Produce(nTime);
			if( tmp1 == 0 && tmp2 == 0)
				break;
			nTime++;
		}
	}
	return 0;
}

總結:老師的程式碼類分的很清晰,儘量減少main函式中的操作,而自己在這一塊做的不是很好,這個是主要的問題,其他的在程式碼中已經標出來了。string中的c_str( )函式的使用方法和介紹:

https://blog.csdn.net/ls_6468/article/details/79312585

https://blog.csdn.net/changqing5818/article/details/51276245

相關文章