程序設計與算法(三)C++面向對象程序設計 (北大MOOC)


  程序設計實習MOOC / 程序設計與算法(三)測驗和作業題匯總(2022寒假)

  ( 僅作參考,過OJ但可能有錯誤 )

  001:簡單的swap

#include <iostream>
using namespace std;
class A
{
    public:
    int x;
    int getX() { return x; }    
};
void swap(
A &a, A &b //類對象的引用
)
{
    int  tmp = a.x;
    a.x = b.x;
    b.x = tmp;
}
int main()
{
    A a,b;
    a.x = 3;
    b.x = 5;
    swap(a,b);
    cout << a.getX() << "," << b.getX();
    return 0;
}
View Code

  002:難一點的swap

#include <iostream>
using namespace std;

void swap(
int* &a, int* &b //指針的引用
)
{
    int * tmp = a;
    a = b;
    b = tmp;
}
int main()
{
    int a = 3,b = 5;
    int * pa = & a;
    int * pb = & b;
    swap(pa,pb); //交換的是指針的指向,並不是交換的a,b
    cout << *pa << "," << * pb;
    return 0;
}
View Code

  003:好怪異的返回值

#include <iostream>
using namespace std;
// 在此處補充你的代碼
int&  //返回引用,可以作為左值
getElement(int * a, int i)
{
    return a[i];
}
int main()
{
    int a[] = {1,2,3};
    getElement(a,1) = 10; //函數的返回值為左值,返回值類型為引用
    cout << a[1] ;
    return 0;
}
View Code

  004:神秘的數組初始化 

//004:神秘的數組初始化
#include <iostream>
using namespace std;

int main()
{
    int * a[] = {  //指針數組
    // 在此處補充你的代碼
        NULL, NULL, new int[1], new int[6]  
    };
    
    *a[2] = 123;    //指針a[2] 分配空間,其實一個空間就夠了 new int[1]
    a[3][5] = 456;  //指針a[3] 分配空間,下標為5,空間最少要6
    if(! a[0] ) {   //指針a[0]為空
        cout << * a[2] << "," << a[3][5];
    }
    return 0;
}
View Code

  005:編程填空:學生信息處理程序

//005:編程填空:學生信息處理程序

/*
實現一個學生信息處理程序,計算一個學生的四年平均成績。
要求實現一個代表學生的類,並且類中所有成員變量都是【私有的】。
補充下列程序中的 Student 類以實現上述功能。
輸入:
Tom Hanks,18,7817,80,80,90,70
輸入數據為一行,包括:
姓名,年齡,學號,第一學年平均成績,第二學年平均成績,第三學年平均成績,第四學年平均成績。
其中姓名為由字母和空格組成的字符串(輸入保證姓名不超過20個字符,並且空格不會出現在字符串兩端),
年齡、學號和學年平均成績均為非負整數。信息之間用逗號隔開。
輸出:
Tom Hanks,18,7817,80
輸出一行數據,包括:
姓名,年齡,學號,四年平均成績。
信息之間用逗號隔開

 */
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <cstdlib>
using namespace std;

class Student
{
// 在此處補充你的代碼
    char name[20]; //scanf("%[^','']",name);
    int age;  //非負整數 年齡
    int id;   //非負整數 學號
    int s_ave4[4]; //非負整數 1-4學年平均成績
    double ave; // 4年的平均成績
public:
    void input()
    {
        char comma; //接收逗號
        scanf("%[^','']",name);
        cin >> comma >> age >> comma >> id;
        for(int i=0; i<4; i++)
            cin >> comma >> s_ave4[i];
    }
    void calculate()
    {
        double sum = 0.0;
        for(int i=0; i<4; ++i)
            sum += s_ave4[i];
        ave = sum / 4.0;
    }
    void output()
    {
        cout << name << "," << age << "," << id << "," << ave << endl;
    }
};

int main()
{
    Student student;        // 定義類的對象
    student.input();        // 輸入數據
    student.calculate();    // 計算平均成績
    student.output();       // 輸出數據
}
View Code

  006:奇怪的類復制

#include <iostream>
using namespace std;
class Sample
{
public:
    int v;
// 在此處補充你的代碼
public:
    Sample():v(0) {}             //無參構造
    Sample(int v):v(v) {} //有參構造
    Sample( const Sample&s )  //拷貝構造
    {
        v = s.v + 2; // +2
    }
};
void PrintAndDouble(Sample o)
{
    cout << o.v;
    cout << endl;
}
int main()
{
    Sample a(5);
    Sample b = a; //調用拷貝構造+2 修改對象b
    PrintAndDouble(b); //調用拷貝構造+2 修改對象b 輸出9
    Sample c = 20;
    PrintAndDouble(c); //調用拷貝構造+2 修改對象c  輸出22
    Sample d;
    d = a;         //調用拷貝構造 +2 修改對象d
    cout << d.v;
    return 0;
}
View Code

  007:返回什么才好呢

#include <iostream>
using namespace std;
class A {
public:
    int val;

    A(int val):val(val){} //有參
    A():val(123){}  //無參
    A& GetObj(){      //返回對象引用 左值
        return *this;
    }
};
int main()
{
    int m,n;
    A a;
    cout << a.val << endl;
    while(cin >> m >> n) {
        a.GetObj() = m;  //左值
        cout << a.val << endl;
        a.GetObj() = A(n); //左值
        cout << a.val<< endl;
    }
    return 0;
}
View Code

  008:超簡單的復數類 

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Complex {
private:
    double r,i;
public:
    void Print() {
        cout << r << "+" << i << "i" << endl;
    }
// 在此處補充你的代碼
    Complex():r( 0.0 ), i( 0.0 ) {}  //無參
    Complex( const char* str ):r( atoi(str) ), i( atoi(str+2) ) {} //有參 const char*
};
int main() {
    Complex a;
    a = "3+4i"; a.Print();
    a = "5+6i"; a.Print();
    return 0;
}
View Code

  009:哪來的輸出

#include <iostream>
using namespace std;
class A {
    public:
        int i;
        A(int x) { i = x; }
// 在此處補充你的代碼
    ~A(){ cout << i << endl; }
};
int main()
{
    A a(1);
    A * pa = new A(2);
    delete pa;
    return 0;
}
View Code

  011:Big & Base 封閉類問題

#include <iostream>
#include <string>
using namespace std;
class Base {
public:
    int k;
    Base(int n):k(n) { }
};
class Big
{
public:
    int v;
    Base b; //類對象 類組合
// 在此處補充你的代碼
    Big(int n):v(n),b(n) { }
};
int main()
{
    int n;
    while(cin >>n) {
        Big a1(n);
        Big a2 = a1;
        cout << a1.v << "," << a1.b.k << endl;
        cout << a2.v << "," << a2.b.k << endl;
    }
}
View Code

  012:這個指針哪來的

#include <iostream>
using namespace std;

struct A
{
    int v;
    A(int vv):v(vv) { }
// 在此處補充你的代碼
    const A* getPointer()const { return this;} //指針是const 函數是const
};

int main()
{
    const A a(10);
    const A * p = a.getPointer();
    cout << p->v << endl;
    return 0;
}
View Code

  013:魔獸世界之一:備戰

#include <iostream>
#include <string>
#include <iomanip>
#include <deque>
#include <map>

using namespace std;

//武士抽象類Warrior
class Warrior
{
protected:
    int time;    //降生時間---
    int number;  //編號---
    string name; //戰士名稱
    int strength;//戰士生命值
public:
    Warrior(int time, int number, string name, int strength)
        :time(time),number(number),name(name),strength(strength)
    {
        //
    }
};

// "iceman","lion","wolf","ninja","dragon"
class Iceman:public Warrior
{
public:
    Iceman(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
};
class Lion:public Warrior
{
public:
    Lion(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
};
class Wolf:public Warrior
{
public:
    Wolf(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
};
class Ninja:public Warrior
{
public:
    Ninja(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
};
class Dragon:public Warrior
{
public:
    Dragon(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
};


//抽象類Headquarter
class Headquarter
{    
private:
    string color; //司令部顏色
    int m;        //司令部生命元
    bool stopped; //停止創建標志
    int time;     //司令部創建時間
    int number;   //司令部創建武士編號
    
    map<string, int > strengths;  //各種武士的生命值
    map<string,int> count;     //統計各種武士的個數
protected:
    deque<string> warriorSequence; //制造武士次序的隊列    紅藍司令部不同
    
private:
    string getWarriorSequence()     //按次序獲取武士名稱
    {
        string wName = warriorSequence.front();
        warriorSequence.pop_front();
        warriorSequence.push_back(wName);
        return wName;
    }
    void countWarriorType(string name)  //統計各種武士個數
    {
        ++count[name];
    }  
    void printCreatedWarrior(string wName,int strength,int count)//打印創建的武士
    {
        cout<<setfill('0')<<setw(3)<<time<<" "<<color<<" "<<wName  
            <<" "<<number<<" born with strength "<<strength<<","
            <<count<<" "<<wName<<" in "<<color<<" headquarter"<<endl;
    }
    void printOver()  //打印結束創建
    {
        cout<<setfill('0')<<setw(3)<<time
            <<" "<<color<<" headquarter stops making warriors"<<endl;
    }

public:
    Headquarter(string color, int m, map<string,int>& strengths ):
        color(color),m(m),stopped(false),time(0),number(1),strengths(strengths) { }
    //工廠方法模式
    void CreateWarrior(  )
    {
        if(stopped) return; //已經停止了返回

        int cnt = warriorSequence.size(); //隊列武士種類
        for(int i=0; i<cnt; ++i)  //隊列中按順序查找,是否有可以創建的武士
        {
            Warrior* w = NULL;
            string wName = getWarriorSequence(); //按順序返回一個武士名

            if( wName=="iceman" )        w = new Iceman(time, number, "iceman", strengths["iceman"]);
            else if( wName=="lion" )    w = new Lion(time, number, "lion", strengths["lion"]);
            else if( wName=="wolf" )    w = new Wolf(time, number, "wolf", strengths["wolf"]);
            else if( wName=="ninja" )   w = new Ninja(time,number, "ninja", strengths["ninja"]);
            else if( wName=="dragon" )    w = new Dragon(time, number, "dragon", strengths["dragon"]);

            if(strengths[wName]<=m)  //可以創建
            {
                countWarriorType( wName ); //統計各種武士的個數
                m -= strengths[wName];      //司令部生命元減少 -- 去掉可建造武士生命值
                printCreatedWarrior( wName, strengths[wName], count[wName] ); //打印創建的武士
                time++;    //降生時間++
                number++;  //降生編號++
                return; //返回
            }
        }
        //停止創建
        stopped = true;
        printOver();   //打印結束創建
    }
    bool getStopped()
    {
        return stopped;
    }
};

class RedHeadquarter:public Headquarter
{

public:
    RedHeadquarter(string color,int m, map<string,int>& strengths ):Headquarter(color,m,strengths)
    {
        warriorSequence = {"iceman","lion","wolf","ninja","dragon"}; //紅色蘭司令部武士創建次序
    }
};

class BlueHeadquarter:public Headquarter
{
public:
    BlueHeadquarter(string color,int m, map<string,int>& strengths ):Headquarter(color,m,strengths)
    {
        warriorSequence = {"lion","dragon","ninja","iceman","wolf"}; //藍色蘭司令部武士創建次序
    }
};

int main()
{
    int num;//測試組數
    cin >> num;
    for(int i=1; i<=num; i++)
    {
        cout<<"Case:"<<i<<endl; //Case:

        int m;  //司令部生命值
        map<string, int > strengths; //各種武士的生命值
        cin >> m >> strengths["dragon"] >> strengths["ninja"] >> 
            strengths["iceman"] >> strengths["lion"] >> strengths["wolf"]; //輸入司令部及各種武士生命值
            
        RedHeadquarter redH("red",m,strengths);    //紅色司令部對象
        BlueHeadquarter blueH("blue",m,strengths); //藍色司令部對象
        
        //紅藍陣營武士同時制造並輸出
        while(!redH.getStopped()||!blueH.getStopped())
        {
            redH.CreateWarrior( );
            blueH.CreateWarrior( );
        }
    }

    return 0;
}
View Code

  014:MyString (    注: 要重寫拷貝構造函數(深拷貝)   )

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class MyString
{
    char * p;
public:
    MyString(const char * s)
    {
        if (s)
        {
            p = new char[strlen(s) + 1];
            strcpy(p, s);
        }
        else
            p = NULL;

    }
    ~MyString()
    {
        if (p)
            delete[] p;
    }
    
    MyString(const MyString& ms) //拷貝構造( 深拷貝 )
    {
        //再賦值
        if(ms.p) //p不空
        {
            p = new char[strlen(ms.p) + 1]; //申請空間
            strcpy(p, ms.p); //copy內容
        }
        else
        {
            p = NULL;
        }
    }
    
    void Copy(const char *s) //Copy成員函數
    {
        //先清理空間
        if (p) //如果對象成員p不空
        {
            delete[] p; //釋放空間
            p = NULL;   //置空
        }
        //再賦值
        if(s) //s不空
        {
            p = new char[strlen(s) + 1]; //申請空間
            strcpy(p, s); //copy內容
        }
    }
    
    friend ostream & operator<<(ostream & os, const MyString & ms) //重載<<運算符( 輸出對象)
    {
        os << ms.p;
        return os;
    }
    
    MyString & operator =(const MyString &s) // =運算符重載 (對象賦值)
    {
        if (this == &s) //指針指向參數對象 是同一對象
            return *this; //返回對象
        //先清理空間
        if (p)
        {
            delete[] p; //釋放空間
            p = NULL;   //置空
        }
        //再賦值
        if (s.p)
        {
            p = new char[strlen(s.p) + 1]; //申請空間
            strcpy(p, s.p); //copy內容
        }
        return *this;
    }
};

int main()
{
    char w1[200], w2[100];
    while (cin >> w1 >> w2)
    {
        MyString s1(w1), s2 = s1; //有參構造 拷貝構造( 重寫 )
        MyString s3(NULL); //有參構造
        s3.Copy(w1); //Copy成員函數
        cout << s1 << "," << s2 << "," << s3 << endl; //輸出對象

        s2 = w2; //有參構造( 類型轉換 )  重載=運算符
        s3 = s2; //重載=運算符
        s1 = s3; //重載=運算符
        cout << s1 << "," << s2 << "," << s3 << endl;
    }
}
View Code

  015:看上去好坑的運算符重載

/*

    在 C++ 中,類型的名字(包括類的名字)本身也是一種運算符,即類型強制轉換運算符。
類型強制轉換運算符是單目運算符,也可以被重載,但只能重載為成員函數,不能重載為全局函數。
經過適當重載后,(類型名)對象,這個對對象進行強制類型轉換的表達式就等價於
對象.operator 類型名(),即變成對運算符函數的調用。

輸入
多組數據,每組一行,整數n
20
30
輸出
對每組數據,輸出一行,包括兩個整數, n-5和n - 8 

*/

#include <iostream>
using namespace std;
class MyInt
{
    int nVal;
public:
    MyInt( int n)
    {
        nVal = n ;
    }
// 在此處補充你的代碼
    friend ostream& operator << (ostream& o, MyInt& mi)
    {
        o << mi.nVal;
        return o;
    }
    MyInt& operator - ( int i)
    {
        nVal -= i;
        return *this;
    }
    operator int()  //類型強制轉換運算符 int 重載
    {
        return nVal;
    }
};
int Inc(int n)
{
    return n + 1;
}
int main ()
{
    int n;
    while(cin >>n)
    {
        MyInt objInt(n);
        objInt-2-1-3;
        cout << Inc(objInt);
        cout <<",";
        objInt-2-1;
        cout << Inc(objInt) << endl;
    }
    return 0;
}
View Code

  016:驚呆!Point竟然能這樣輸入輸出

/* 
輸入
2 3
4 5
輸出
2,3
4,5 
*/

#include <iostream> 
using namespace std;
class Point { 
    private: 
        int x; 
        int y; 
    public: 
        Point() { };
// 在此處補充你的代碼
    friend istream& operator >> (istream& i, Point &p){ //p要輸入不能是const
        i >> p.x >> p.y;
        return i;
    }
    friend ostream& operator << (ostream& o,const Point &p){
        o << p.x << "," << p.y;  //C++ Primer一書 也建議函數不輸出 endl
        return o;
    }
}; 
int main() 
{ 
     Point p;
     while(cin >> p) {
         cout << p << endl;
     }
    return 0;
}
View Code

  017:二維數組類

#include <iostream>
#include <cstring>
using namespace std;

class Array2
{
    int** ptr; //二維指針,指向一維指針數組
    int x, y;     //二維數組下標
public:
    Array2() :ptr(NULL),x(0),y(0) {} //無參構造
    Array2(int x, int y):x(x),y(y)   //有參構造
    {
        ptr = new int *[x]; //分配指針數組空間
        for (int i = 0; i < x; i++)
        {
            ptr[i] = new int[y]; // 分配指針數組里的指針指向的空間
        }
    }
    int* operator[](int n) //重載[]運算符 返回類型 int*
    {
        return ptr[n];
    }
    int operator()(int x, int y)  //重載()運算符 a(i,j) 函數對象
    {
        return ptr[x][y];
    }
    Array2& operator=(const Array2& a) //重載=運算符 b = a;
    {
        if (ptr != NULL)
        {
            for (int i = 0; i < x; i++)
            {
                delete[]ptr[i]; //釋放指針數組里指針指向的空間
            }
            delete []ptr; //釋放指針數組空間
        }
        ptr = new int*[a.x];
        for (int i = 0; i < a.x; i++)
        {
            ptr[i] = new int[a.y]; //分配二維空間--指針數組的指針指向的空間
            memcpy(ptr[i], a.ptr[i], sizeof(int)*a.y); //復制內容
        }
        x = a.x;
        y = a.y;
        return *this;
    }
    ~Array2() // 析構
    {
        if (ptr != NULL)
        {
            for (int i = 0; i < x; i++)
            {
                delete[]ptr[i]; //釋放指針數組指向的空間
            }
            delete []ptr; //釋放指針數組空間
        }
    }
};

int main()
{
    Array2 a(3,4);//有參構造
    int i,j;
    for(  i = 0; i < 3; ++i )
        for(  j = 0; j < 4; j ++ )
            a[i][j] = i * 4 + j; // a[i] 重載成 ptr[i] --- int*---[j] int*指向的空間賦值
    for(  i = 0; i < 3; ++i )
    {
        for(  j = 0; j < 4; j ++ )
        {
            cout << a(i,j) << ","; //函數對象 即重載了()運算符的對象
        }
        cout << endl;
    }
    cout << "next" << endl;
    Array2 b;  //無參構造
    b = a;         //Array2& operator=(const Array2& a) //重載=運算符
    for(  i = 0; i < 3; ++i )
    {
        for(  j = 0; j < 4; j ++ )
        {
            cout << b[i][j] << ",";  // b[i] 重載成 ptr[i] 為 int*
        }
        cout << endl;
    }
    return 0;
}
View Code

  018:別叫,這個大整數已經很簡化了!

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;

const int MAX = 110;

class CHugeInt
{
private:
    int *a;
    int index; //下標
public:
    //無參構造函數
    CHugeInt()
    {
        a = new int[MAX];                  //分配空間
        memset(a, 0, sizeof(int) * MAX);  //a置0
        index = 1;                        //下標置1        
        
    }
    //復制構造函數
    CHugeInt(const CHugeInt& x)
    {        
        index = x.index;
        a = new int[MAX];
        memset(a, 0, sizeof(int) * MAX);
        //拷貝a
        for(int i = 1; i <= index; i++)
        {
            a[i] = x.a[i];
        }
    }
    //析構函數
    ~CHugeInt()
    {
        if(a)
        {
            delete [] a;
            a = NULL;
        }        
    }
    //int參數構造函數
    CHugeInt(int n)
    {    
        a = new int[MAX];
        memset(a, 0, sizeof(int) * MAX);//a值0
        
        index = !n ? 1 : 0;//參數n為0,下標值1 ,否則值0
        while(n)
        {
            a[++index] = n % 10;
            n /= 10;
        }
    }
    //參數為char *構造函數
    CHugeInt(const char *c)
    {
        a = new int[MAX];
        memset(a, 0, sizeof(int) * MAX);
        index = strlen(c);
        for(int i = index - 1; i >= 0; i--)
            a[index - i] = c[i] - '0';
    }
    //重載[]運算符
    int& operator[](int x)
    {
        return a[x];
    }
    //兩對象賦值,重載=運算符,成員函數
    CHugeInt& operator =(const CHugeInt& x)
    {
        if( this == &x )
        {
            return *this;
        }
        if(a)
        {
            delete[] a;
            a = NULL;
        }
        if(x.a)
        {
            a = new int[MAX];
            memset(a,0,sizeof(*a));
            index = x.index;
            for(int i = 1; i <= index; i++)
                a[i] = x.a[i];
        }        
        return *this;
    }
    //兩對象相加,重載=運算符,友元函數
    friend CHugeInt operator +(CHugeInt a, CHugeInt b)
    {
        CHugeInt c;
        c.index = max(a.index, b.index);
        
        for(int i = 1; i <= c.index; i++)
            c[i] = a[i] + b[i];          //重載[]運算符
        for(int i = 1; i <= c.index; i++)//處理進位
        {
            if(c[i] >= 10)
            {
                if(i == c.index)           //擴充
                {
                    c.index++;
                }                    
                c[i + 1] += c[i] / 10;     //進位
                c[i] %= 10;                //取余
            }
        }        
        return c;
    }
    //CHugeInt類對象輸出
    friend ostream& operator << (ostream& os, const CHugeInt& x)
    {
        for(int i = x.index; i >= 1; i--) //逐位輸出
            os << x.a[i];
        return os;
    }
    // int 與對象相加
    friend CHugeInt operator +(int a, const CHugeInt& b)
    {
        return CHugeInt(a) + b;//兩個CHugeInt類對象相加
    }
    //+=
    CHugeInt& operator +=(int x)
    {
        *this = *this + CHugeInt(x);
        return *this;
    }
    //前置++
    CHugeInt& operator ++()
    {
        *this = *this + CHugeInt(1);
        return *this;
    }
    //后置++
    CHugeInt operator ++(int)
    {
        CHugeInt tmp = *this;
        *this = CHugeInt(1) + *this;
        return tmp;
    }
};
int  main()
{
    char s[210];
    int n;

    while (cin >> s >> n)
    {
        CHugeInt a(s); //const char*
        CHugeInt b(n); //int n    
        
        //friend ostream& operator << (ostream& os, const CHugeInt& x)    
        //friend CHugeInt operator +(CHugeInt a, CHugeInt b)
        cout << a + b << endl; 
        //friend CHugeInt operator +(int a, const CHugeInt& b)
        cout << n + a << endl; 
        //調用參數為int的構造函數,n會類型轉換為對象
        cout << a + n << endl; 
        //CHugeInt& operator +=(int x)
        b += n;  
        //CHugeInt& operator ++()
        cout  << ++ b << endl; 
        //CHugeInt operator ++(int)
        cout << b++ << endl;   
        cout << b << endl;    
    }
    return 0;
}
View Code

  019:全面的MyString

#include <cstdlib>
#include <iostream>
using namespace std;
int strlen(const char * s)
{
    int i = 0;
    for(; s[i]; ++i);
    return i;
}
void strcpy(char * d,const char * s)
{
    int i = 0;
    for( i = 0; s[i]; ++i)
        d[i] = s[i];
    d[i] = 0;

}
int strcmp(const char * s1,const char * s2)
{
    for(int i = 0; s1[i] && s2[i] ; ++i)
    {
        if( s1[i] < s2[i] )
            return -1;
        else if( s1[i] > s2[i])
            return 1;
    }
    return 0;
}
void strcat(char * d,const char * s)
{
    int len = strlen(d);
    strcpy(d+len,s);
}
class MyString
{
    char *p;
public:
    //1、 構造函數----創建對象   
    MyString()//無參構造函數--
    {
        p = NULL;
    };
    MyString(const char *s)//有參構造函數--char *
    {
        p = new char[strlen(s)+ 1];
        strcpy(p,s);
    }
    MyString(const MyString & x) //拷貝構造--深拷貝
    {
        if(x.p)
        {
            p = new char[strlen(x.p)+1];
            strcpy(p,x.p);
        }
        else
            p = NULL;
    }
    //2、 析構----釋放空間
     ~MyString()
    {
        if(p)delete []p;
    }
    
    //3、友元函數----輸出對象
    friend ostream& operator << (ostream& os, const MyString &s)
    {
        if(s.p)os << s.p;
        return os;
    }
    
    //4.重載=運算符----對象向對象賦值
    MyString & operator=(const MyString & x)
    {
        if(p == x.p)
            return *this;
        if(p)
            delete[] p;
        if(x.p)
        {
            p = new char[strlen(x.p)+1];
            strcpy(p,x.p);
        }
        else
            p = NULL;
        return *this;
    }
    
    //5.重載[] 返回引用 可以修改字符
    char & operator[](int x)
    {
        return p[x];
    }
    //6.對象 +  對象
    MyString operator+(const MyString &ms)
    {
        MyString temp;
        temp.p = new char[strlen(p) + strlen(ms.p)+1];
        strcpy(temp.p, p);
        strcat(temp.p, ms.p);
        return temp;
    }
    //7.對象 += 字符串 ----字符串先轉對象--構造
    MyString& operator +=(const char *s)
    {
        *this = *this + MyString(s); //修改了字符串
        return *this;
    }
    //8.字符串 +  對象 ----字符串先轉對象--構造 
    //對象  + 字符串,字符串會強轉為對象
    friend MyString operator+(const char*str, const MyString &ms)
    {
        return MyString(str) + ms;
    }
    //9.重載<類對象比較
    bool operator <(const MyString &s)
    {
        return strcmp(p,s.p)==-1;
    }
    //10.重載> 類對象比較
    bool operator >(const MyString &s)
    {
        return strcmp(p,s.p)==1;
    }
    //11.重載== 類對象比較
    bool operator ==(const MyString &s)
    {
        return strcmp(p,s.p)==0;
    }
    //12.()運算符重載 substr 
    char* operator()(int start,int len) //第二個參數是復制的長度
    {
        char* temp = new char[len];
        int index = 0; 
        while( index < len ){
            temp[index++] = p[start++];
        }        
        temp[index] = '\0';
        return temp;
    }
};


int CompareString( const void * e1, const void * e2)
{
    MyString * s1 = (MyString * ) e1;
    MyString * s2 = (MyString * ) e2;
    if( * s1 < *s2 )
        return -1;
    else if( *s1 == *s2)
        return 0;
    else if( *s1 > *s2 )
        return 1;
}
int main()
{
    MyString s1("abcd-"),s2,s3("efgh-"),s4(s1); //有參構造、 無參構造、 拷貝構造
    MyString SArray[4] = {"big","me","about","take"};
    cout << "1. " << s1 << s2 << s3<< s4<< endl; //重載 << 運算符
    s4 = s3;                                    // 重載 = 運算符
    s3 = s1 + s3;    // 重載 + 運算符--- 成員函數---兩對象相加 
    cout << "2. " << s1 << endl;
    cout << "3. " << s2 << endl;
    cout << "4. " << s3 << endl;
    cout << "5. " << s4 << endl;
    cout << "6. " << s1[2] << endl; //重載 [] 運算符
    s2 = s1;
    s1 = "ijkl-"; //字符串默認強轉--調用構造函數
    s1[2] = 'A' ;
    cout << "7. " << s2 << endl;
    cout << "8. " << s1 << endl;
    s1 += "mnop";
    cout << "9. " << s1 << endl;
    s4 = "qrst-" + s2;
    cout << "10. " << s4 << endl;
    s1 = s2 + s4 + " uvw " + "xyz";
    cout << "11. " << s1 << endl;
    qsort(SArray,4,sizeof(MyString),CompareString);
    for( int i = 0; i < 4; i ++ )
        cout << SArray[i] << endl;
    //s1的從下標0開始長度為4的子串
    cout << s1(0,4) << endl;
    //s1的從下標5開始長度為10的子串
    cout << s1(5,10) << endl;
    return 0;
}
View Code

  020:繼承自string的MyString

#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class MyString:public string
{
public: 
    MyString():string(){ };                   //無參構造 
    MyString(const char* str):string(str){ }; //有參構造,const char* 強轉 或者 叫類型轉換    
    MyString(const string& str):string(str){};//有參構造,對象強轉 或者 叫類型轉換
    
    MyString operator () (int i, int j)        //函數對象用到繼承自string的substr函數
    {  
        return substr(i, j);  //子串 返回的是string
    } 
};


int main()
{
    MyString s1("abcd-"),s2,s3("efgh-"),s4(s1);
    MyString SArray[4] = {"big","me","about","take"};
    cout << "1. " << s1 << s2 << s3<< s4<< endl;
    s4 = s3;
    s3 = s1 + s3;
    cout << "2. " << s1 << endl;
    cout << "3. " << s2 << endl;
    cout << "4. " << s3 << endl;
    cout << "5. " << s4 << endl;
    cout << "6. " << s1[2] << endl;
    s2 = s1;
    s1 = "ijkl-";
    s1[2] = 'A' ;
    cout << "7. " << s2 << endl;
    cout << "8. " << s1 << endl;
    s1 += "mnop";
    cout << "9. " << s1 << endl;
    s4 = "qrst-" + s2;
    cout << "10. " << s4 << endl;
    s1 = s2 + s4 + " uvw " + "xyz";
    cout << "11. " << s1 << endl;
        sort(SArray,SArray+4);
    for( int i = 0;i < 4;i ++ )
    cout << SArray[i] << endl;
    //s1的從下標0開始長度為4的子串
    cout << s1(0,4) << endl;
    //s1的從下標5開始長度為10的子串
    cout << s1(5,10) << endl;
    return 0;
}
View Code

  021:魔獸世界之二:裝備

#include <iostream>
#include <string>
#include <iomanip>
#include <deque>
#include <map>

using namespace std;

//武士抽象類Warrior
class Warrior
{
protected:
    int time;    //降生時間---
    int number;  //編號---
    string name; //戰士名稱
    int strength;//戰士生命值
    const char* weapon[3]; 
public:
    Warrior(int time, int number, string name, int strength)
        :time(time),number(number),name(name),strength(strength),weapon{ "sword", "bomb", "arrow" }
    {
        //
    }
    virtual void printInfo() = 0; //純虛函數
};

// "iceman","lion","wolf","ninja","dragon"
class Iceman:public Warrior
{
public:
    Iceman(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
    void printInfo(){
        cout << "It has a " << weapon[ number%3 ] << endl;
    }
};
class Lion:public Warrior
{
    int loyalty;
public:
    Lion(int time, int number, string name, int strength, int loyalty ):
        Warrior(time, number, name, strength), loyalty(loyalty)
    {
        
    }
    void printInfo(){
        cout << "It's loyalty is " << loyalty << endl;
    }
};
class Wolf:public Warrior
{
public:
    Wolf(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
    void printInfo(){} //空實現
};
class Ninja:public Warrior
{
public:
    Ninja(int time, int number, string name, int strength):Warrior(time, number, name, strength) {}
    void printInfo(){
        cout << "It has a " << weapon[ number%3 ] << " and a " << weapon[ (number+1)%3 ] << endl;
    }
};
class Dragon:public Warrior
{
    double morale;
public:
    Dragon(int time, int number, string name, int strength, double morale):
                Warrior(time, number, name, strength),morale(morale)
    {
        
    }
    void printInfo(){
        cout << "It has a " << weapon[ number%3 ] << ",and it's morale is " 
            << setiosflags(ios::fixed) << setprecision(2) <<  morale  << endl;
    }
};


//抽象類Headquarter
class Headquarter
{    
private:
    string color; //司令部顏色
    int m;        //司令部生命元
    bool stopped; //停止創建標志
    int time;     //司令部創建時間
    int number;   //司令部創建武士編號
    
    map<string, int > strengths;  //各種武士的生命值
    map<string,int> count;     //統計各種武士的個數
protected:
    deque<string> warriorSequence; //制造武士次序的隊列    紅藍司令部不同
    
private:
    string getWarriorSequence()     //按次序獲取武士名稱
    {
        string wName = warriorSequence.front();
        warriorSequence.pop_front();
        warriorSequence.push_back(wName);
        return wName;
    }
    void countWarriorType(string name)  //統計各種武士個數
    {
        ++count[name];
    }  
    void printCreatedWarrior(string wName,int strength,int count)//打印創建的武士
    {
        cout<<setfill('0')<<setw(3)<<time<<" "<<color<<" "<<wName  
            <<" "<<number<<" born with strength "<<strength<<","
            <<count<<" "<<wName<<" in "<<color<<" headquarter"<<endl;
    }
    void printOver()  //打印結束創建
    {
        cout<<setfill('0')<<setw(3)<<time
            <<" "<<color<<" headquarter stops making warriors"<<endl;
    }

public:
    Headquarter(string color, int m, map<string,int>& strengths ):
        color(color),m(m),stopped(false),time(0),number(1),strengths(strengths) { }
    //工廠方法模式
    void CreateWarrior(  )
    {
        if(stopped) return; //已經停止了返回

        int cnt = warriorSequence.size(); //隊列武士種類
        for(int i=0; i<cnt; ++i)  //隊列中按順序查找,是否有可以創建的武士
        {
            Warrior* w = NULL;
            string wName = getWarriorSequence(); //按順序返回一個武士名

            if( wName=="iceman" )        
                w = new Iceman(time, number, "iceman", strengths["iceman"]);
            else if( wName=="lion" )    
                w = new Lion(time, number, "lion", strengths["lion"],m-strengths["lion"]);
            else if( wName=="wolf" )    
                w = new Wolf(time, number, "wolf", strengths["wolf"]);
            else if( wName=="ninja" )   
                w = new Ninja(time,number, "ninja", strengths["ninja"]);
            else if( wName=="dragon" ){
                w = new Dragon( time, number, "dragon", strengths["dragon"],
                    1.0*(m-strengths["dragon"])/strengths["dragon"] );    
            }    
                    
            if(strengths[wName]<=m)  //可以創建
            {
                countWarriorType( wName ); //統計各種武士的個數
                m -= strengths[wName];      //司令部生命元減少 -- 去掉可建造武士生命值
                printCreatedWarrior( wName, strengths[wName], count[wName] ); //打印創建的武士
                w->printInfo(); //輸出武士信息
                time++;    //降生時間++
                number++;  //降生編號++
                return; //返回
            }
        }
        //停止創建
        stopped = true;
        printOver();   //打印結束創建
    }
    bool getStopped()
    {
        return stopped;
    }
};

class RedHeadquarter:public Headquarter
{

public:
    RedHeadquarter(string color,int m, map<string,int>& strengths ):Headquarter(color,m,strengths)
    {
        warriorSequence = {"iceman","lion","wolf","ninja","dragon"}; //紅色蘭司令部武士創建次序
    }
};

class BlueHeadquarter:public Headquarter
{
public:
    BlueHeadquarter(string color,int m, map<string,int>& strengths ):Headquarter(color,m,strengths)
    {
        warriorSequence = {"lion","dragon","ninja","iceman","wolf"}; //藍色蘭司令部武士創建次序
    }
};

int main()
{
    int num;//測試組數
    cin >> num;
    for(int i=1; i<=num; i++)
    {
        cout<<"Case:"<<i<<endl; //Case:

        int m;  //司令部生命值
        map<string, int > strengths; //各種武士的生命值
        cin >> m >> strengths["dragon"] >> strengths["ninja"] >> 
            strengths["iceman"] >> strengths["lion"] >> strengths["wolf"]; //輸入司令部及各種武士生命值
            
        RedHeadquarter redH("red",m,strengths);    //紅色司令部對象
        BlueHeadquarter blueH("blue",m,strengths); //藍色司令部對象
        
        //紅藍陣營武士同時制造並輸出
        while(!redH.getStopped()||!blueH.getStopped())
        {
            redH.CreateWarrior( );
            blueH.CreateWarrior( );
        }
    }

    return 0;
}
View Code

  022:看上去像多態

#include <iostream>
using namespace std;
class B
{
private:
    int nBVal;
public:
    void Print()
    {
        cout << "nBVal="<< nBVal << endl;
    }
    void Fun()
    {
        cout << "B::Fun" << endl;
    }
    B ( int n )
    {
        nBVal = n;
    }
};
// 在此處補充你的代碼 
class D:public B
{
    int nDVal;
public:
    D(int n): B(n*3), nDVal(n)
    {
        
    }    
    void Fun()
    {
        cout << "D::Fun" << endl;
    }
    void Print()
    {
        B::Print();
        cout << "nDVal=" << nDVal << endl;
    }    
};
int main()
{
    B * pb;
    D * pd;
    D d(4);                //D構造 值4,B值4*3=12
    d.Fun();        //D::Fun
    pb = new B(2);      //B構造 值2
    pd = new D(8);      //D構造 值8,B值8*3=24
    pb -> Fun();    //B::Fun
    pd->Fun();      //D::Fun
    
    pb->Print ();   //nBVal=2
    pd->Print ();   //nBVal=24 //nDVal=8  //打印B、D值
    pb = & d;           
    pb->Fun();      //B::Fun
    pb->Print();    //nBVal=12  //打印B值//調用B類Print()函數
    return 0;
}
View Code

  023:Fun和Do

#include <iostream>
using namespace std;
class A
{
private:
    int nVal;
public:
    void Fun()
    {
        cout << "A::Fun" << endl;
    };
    void Do()
    {
        cout << "A::Do" << endl;
    }
};
class B:public A
{
public:
    virtual void Do()
    {
        cout << "B::Do" << endl;
    }
};
class C:public B
{
public:
    void Do( )
    {
        cout <<"C::Do"<<endl;
    }
    void Fun()
    {
        cout << "C::Fun" << endl;
    }
};
void Call(
    B& p
)
{
    p.Fun(); //B 繼承 A的Fun()函數
    p.Do();  //B有Do()虛函數,真實對象是C,調用C的Do()函數
}
int main()
{
    C c;
    Call( c);
    return 0;
}
View Code

  024:這是什么鬼delete

#include <iostream> 
using namespace std;
class A 
{ 
public:
    A() { }
    //通過基類的指針來刪除派生類的對象時,基類的析構函數應該是虛的
    virtual~A(){ cout << "destructor A" << endl; }
}; 
class B:public A { 
    public: 
    ~B() { cout << "destructor B" << endl; } 
}; 
int main() 
{ 
    A * pa; 
    pa = new B; 
    delete pa; 
    return 0;
}
View Code

  025:怎么又是Fun和Do

#include <iostream>
using namespace std;
class A {
    private:
    int nVal;
    public:
    void Fun()
    { cout << "A::Fun" << endl; };
    virtual void Do()
    { cout << "A::Do" << endl; }
};
class B:public A {
    public:
    virtual void Do()
    { cout << "B::Do" << endl;}
};
class C:public B {
    public:
    void Do( )
    { cout <<"C::Do"<<endl; }
    void Fun()
    { cout << "C::Fun" << endl; }
};
void Call(
    A* p
) {
    p->Fun(); p->Do();
}
int main() {
    Call( new A());
    Call( new C());
    return 0;
}
View Code

  026:編程填空:統計動物數量

#include <iostream>
using namespace std;
// 在此處補充你的代碼
class Animal
{
public:
    static int number;
    virtual ~Animal() { } //基類虛析構
};
int Animal::number = 0;


class Dog:public Animal
{

public:
    static int number;
    Dog()
    {
        number++;
        Animal::number++;
    }
    ~Dog()
    {
        number--;
        Animal::number--;
    }
};
int Dog::number = 0;


class Cat:public Animal
{
public:
    static int number;
    Cat()
    {
        number++;
        Animal::number++;
    }
    ~Cat()
    {
        number--;
        Animal::number--;
    }
};
int Cat::number = 0;

void print()
{
    cout << Animal::number << " animals in the zoo, "
         << Dog::number << " of them are dogs, "
         << Cat::number << " of them are cats" << endl;
}

int main()
{
    print();
    Dog d1, d2;
    Cat c1;
    print();
    Dog* d3 = new Dog();
    Animal* c2 = new Cat;
    Cat* c3 = new Cat;
    print();
    delete c3;
    delete c2;
    delete d3;
    print();
}
View Code

  027:簡單的SumArray

#include <iostream>
#include <string>
using namespace std;
template <class T>
T SumArray( T* begin, T* end )
{
    T temp = *begin++;
    for(T* i=begin; i<end; ++i)
        temp += *i;
    return temp;
}
int main() {
    string array[4] = { "Tom","Jack","Mary","John"};
    cout << SumArray(array,array+4) << endl;
    int a[4] = { 1, 2, 3, 4};  //提示:1+2+3+4 = 10
    cout << SumArray(a,a+4) << endl;
    return 0;
}
View Code

  028:簡單的foreach

#include <iostream>
#include <string>
using namespace std;

template <class T,class T1>  // 2個類型
void MyForeach(T* start, T* end, void (*function)( T1 ))
{
    for(T* p=start; p<end; ++p)
    {
        function(*p); //函數參數 T1 string 、int&
    }        
}
void Print(string s)
{
    cout << s;
}
void Inc(int & n)
{
    ++ n;
}
string array[100];
int a[100];
int main()
{
    int m,n;
    while(cin >> m >> n)
    {
        for(int i = 0; i < m; ++i)
            cin >> array[i];
        for(int j = 0; j < n; ++j)
            cin >> a[j];
        MyForeach(array,array+m,Print);
        cout << endl;
        MyForeach(a,a+n,Inc);
        for(int i = 0; i < n; ++i)
            cout << a[i] << ",";
        cout << endl;
    }
    return 0;
}
View Code

  029:簡單的Filter

#include <iostream>
#include <string>
using namespace std;
// 在此處補充你的代碼

template<class T>
T* Filter( T* start, T* end, T* start1, bool(*function)( T ) )
{
    while( start<end )
    {
        if( function( *start ) )//滿足條件
        {
            *start1++ = *start;
        }
        start++;
    }
    return start1;
}

bool LargerThan2(int n)  //大於2的數
{
    return n > 2;
}
bool LongerThan3(string s)//長度大於3的string
{
    return s.length() > 3;
}

string as1[5] = {"Tom","Mike","Jack","Ted","Lucy"};
string as2[5];
int  a1[5] = { 1,2,3,4,5};
int a2[5];

int main()
{
    string * p = Filter(as1,as1+5,as2,LongerThan3);
    for(int i = 0; i < p - as2; ++i)
        cout << as2[i];
    cout << endl;
    int * p2 = Filter(a1,a1+5,a2,LargerThan2);
    for(int i = 0; i < p2-a2; ++i)
        cout << a2[i] << ",";
    return 0;
}
View Code

  030:你真的搞清楚為啥 while(cin >> n) 能成立了嗎?

#include <iostream>
using namespace std;
class MyCin
{
    bool flag;
public:
    MyCin():flag(true){ }
    MyCin& operator >> (int& n)
    {
        std::cin >> n;
        if( n == -1 ) //輸入值為-1 MyCin對象為false
        {
            flag = false;
        }
        return *this;
    }
    operator bool() //bool運算符重載 判斷MyCin對象的true或false
    {
        return flag;
    }
};
int main()
{
    MyCin m;
    int n1,n2;
    while( m >> n1 >> n2) 
        cout  << n1 << " " << n2 << endl;
    return 0;
}
View Code

  031:山寨版istream_iterator

#include <iostream>
#include <string>
using namespace std;

template <class T>
class CMyistream_iterator
{
private:
    istream& ist; 
    T now; //類型 T 
public:
    CMyistream_iterator(){}
    CMyistream_iterator(istream &ist):ist(ist)//構造函數ist為cin的引用
    {   //同時輸入now的值
        ist >> now;
    }
    T operator*(){  //重載*運算符,返回 now
        return now;
    }
    void operator ++(int){ //重載++運算符 再次輸入覆蓋now
        ist >> now;
    }
};


int main()  
{ 
    int t;
    cin >> t;
    while( t -- ) {
         CMyistream_iterator<int> inputInt(cin);
         int n1,n2,n3;
         n1 = * inputInt; //讀入 n1
         int tmp = * inputInt;
         cout << tmp << endl;
         inputInt ++;   
         n2 = * inputInt; //讀入 n2
         inputInt ++;
         n3 = * inputInt; //讀入 n3
         cout << n1 << " " << n2<< " " << n3 << " ";
         CMyistream_iterator<string> inputStr(cin);
         string s1,s2;
         s1 = * inputStr;
         inputStr ++;
         s2 = * inputStr;
         cout << s1 << " " << s2 << endl;
    }
     return 0;  
}
View Code

  032:這個模板並不難

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
template <class T>  
class myclass {
// 在此處補充你的代碼
    int size;
    T* p;    
public:
    myclass( T* arr, const int size ):size(size)
    {
        p = new T[size]; // !!! 分配空間 T類型
        for(int i = 0; i < size; i++) // 賦值
            p[i] = arr[i];
    }
    ~myclass( ) {
        delete [] p;
    }
    void Show()
    {
        for( int i = 0;i < size;i ++ ) {
            cout << p[i] << ",";
        }
        cout << endl;
    }
};
int a[100];
int main() {
    char line[100];
    while( cin >> line ) {
        myclass<char> obj(line,strlen(line));
        obj.Show();
        int n;
        cin >> n;
        for(int i = 0;i < n; ++i)
            cin >> a[i];
        myclass<int> obj2(a,n);
        obj2.Show();
    }
    return 0;
}
View Code

  033:排序,又見排序!

#include <iostream>
using namespace std;

bool Greater2(int n1,int n2) 
{
    return n1 > n2;
}
bool Greater1(int n1,int n2) 
{
    return n1 < n2;
}
bool Greater3(double d1,double d2)
{
    return d1 < d2;
}

template <class T1,class T2> //T1為for循環變量使用,T2為數據類型使用
void mysort(T1 left, T1 right, bool (*cmp)(T2,T2))
{
    for(T1 i = left; i != right; i++) //冒泡排序 T1為指針類型
    {        
        for(T1 j = i + 1; j != right; j++)
        {
            if( cmp(*j, *i) ) // < *j排在前 ( 比較函數 )
            {
                swap(*j, *i); // *i *j 在前在后一樣
            }    
        }          
    }        
}

#define NUM 5
int main()
{
    int an[NUM] = { 8,123,11,10,4 };
    mysort(an,an+NUM,Greater1); //從小到大排序 
    for( int i = 0;i < NUM; i ++ )
       cout << an[i] << ",";
    mysort(an,an+NUM,Greater2); //從大到小排序 
    cout << endl;
    for( int i = 0;i < NUM; i ++ )
        cout << an[i] << ","; 
    cout << endl;
    double d[6] = { 1.4,1.8,3.2,1.2,3.1,2.1};
    mysort(d+1,d+5,Greater3); //將數組從下標1到下標4從小到大排序 
    for( int i = 0;i < 6; i ++ )
         cout << d[i] << ","; 
    return 0;
}
View Code

  034:goodcopy

#include <iostream>
using namespace std;

template <class T>
struct GoodCopy
{
private:
    T * ptr; //借用空間
public:
    void operator()(T * start,T * end,T * start2)
    {
        int len = end - start;
        ptr = new T[len + 1];
        for(int i = 0;i<len;++i)
            ptr[i] = start[i];
        for(int i = 0;i<len;++i)
            start2[i] = ptr[i];
        delete []ptr;           
    }
};

int a[200];
int b[200];
string c[200];
string d[200];

template <class T>
void Print(T s,T e)
{
    for(; s != e; ++s)
        cout << * s << ",";
    cout << endl;
}

int main()
{
    int t;
    cin >> t;
    while( t -- )
    {
        int m ;
        cin >> m;
        for(int i = 0; i < m; ++i)
            cin >> a[i];
        GoodCopy<int>()(a,a+m,b);
        Print(b,b+m);
        //a,a+m --> a+m/2會覆蓋a數組a+m/2之后的部分
        //所以要借用其他空間保存a數組
        //然后再從其他空間復制回來
        GoodCopy<int>()(a,a+m,a+m/2);//函數對象( 臨時對象 )
        Print( a+m/2, a+m/2+m );    
        for(int i = 0; i < m; ++i)
            cin >> c[i];
        GoodCopy<string>()(c,c+m,d);
        Print(c,c+m);
        //同理
        GoodCopy<string>()(c,c+m,c+m/2);
        Print( c+m/2, c+m/2+m );
    }
    return 0;
}
View Code

  035:按距離排序

#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
template <class T1,class T2>
struct Closer
{
private:
    T1 val;//輸入的值,題目是int型,string型的值
    T2 op; //函數指針,題目是Distance1,Distance2
public:
    Closer( const T1& val, T2 op ):val(val),op(op) { }
    bool operator()( const T1& x, const T1& y )
    {
                                   //1輸入的數字與a數組的每個元素之差的絕對值小的在前面
        if (op(val, x) < op(val, y)//2輸入的字符串長度與b數組的每個元素的長度之差的絕對值小的在前面
                || (op(val, x) == op(val, y)) && x < y) //1差的絕對值相等的,值小的排在前面 比如2與3,2與1之差的絕對值是相等的
            return true;                                //2如果長度相等,字典序小的排在前面
        return false;

    }
};

int Distance1(int n1,int n2)
{
    return abs(n1-n2);
}
int Distance2(const string & s1, const string & s2)
{
    //輸入的字符串長度與b數組的每一個元素的長度的差的絕對值小的在前面
    return abs((int)s1.length()- (int) s2.length());
}

//對數組a按和n的距離從小到大排序后輸出。距離相同的,值小的排在前面。
int a[10] = { 0,3,1,4,7,9,20,8,10,15};
//然后對數組b,按照和s的距離從小到大輸出。距離相同的,字典序小的排在前面
string b[6] = {"American","Jack","To","Peking","abcdefghijklmnop","123456789"};

int main()
{
    int n;
    string s;
    while( cin >> n >> s )
    {
        sort( a,a+10,Closer<int, int (*)(int,int) > (n,Distance1) ); //對象傳進去后會調用()運算符重載
        //Closer<int, int (*)(int ,int) > (n,Distance1) 模板類的函數對象 調用的構造函數
        for(int i = 0; i < 10; ++i)
            cout << a[i] << "," ;
        cout << endl;
        sort( b,b+6,Closer<string,int (*)(const string &,const string &  ) > (s,Distance2) );
        for(int i = 0; i < 6; ++i)
            cout << b[i] << "," ;
        cout << endl;
    }
    return 0;
}
View Code

  036:很難蒙混過關的CArray3d三維數組模板類

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

template <class T>
class CArray3D
{    // 一維的是一條線, 線一行一行的彎曲折疊就成了二維的面
    // 一個一個的面折疊起來就是三維的立體
    class CArray2D
    {
    private:
        int row; //
        int col; //
        T *ptr;  //一維指針
    public:
        CArray2D() :row(0), col(0)
        {
            ptr = new T[1];
        }
        void init(int row, int col)
        {
            this->row = row;
            this->col = col;
            delete[]ptr;
            ptr = new T[ row * col + 1];
        }
        T * operator[](int i) //二維中,每行的首地址
        {
            return (ptr + i * col);//每行的首地址
        }
        operator T*() //重載T類型指針 T* ( 二維對象強轉一維指針 )
        {
            return ptr;
        }
    };
    CArray2D * a;  //二維指針
public:
    CArray3D(int level,int row,int col)
    {
        a = new CArray2D[level];
        for (int i = 0; i < level; ++i)
            a[i].init(row, col); //a[i] 二維對象
    }
    CArray2D& operator[](int i) //返回值為引用,左值
    {
        return a[i]; //二維對象
    }
};

//[]運算符,三維返回的是二維的對象引用,二維返回的是一維的指針,一維返回的是地址中的值

CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
    for(int i = 0; i < 3; ++i)
    {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 4; ++j)
        {
            for(int k = 0; k < 5; ++k)
                cout << a[i][j][k] << "," ;
            cout << endl;
        }
    }
}
void PrintB()
{
    for(int i = 0; i < 3; ++i)
    {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 2; ++j)
        {
            for(int k = 0; k < 2; ++k)
                cout << b[i][j][k] << "," ;
            cout << endl;
        }
    }
}

int main()
{
    int No = 0;
    for( int i = 0; i < 3; ++ i )
    {
        a[i]; // 層 -- 每層都是2維 (二維的對象)
        for( int j = 0; j < 4; ++j )
        {
            a[j][i];//
            for( int k = 0; k < 5; ++k )
                a[i][j][k] = No ++; //
            a[j][i][i];
        }
    }
    PrintA();

    //第一個參數void* a[1]是二維對象 二維類要重載T類型指針T*
    memset(a[1],-1,20*sizeof(int));
    memset(a[1],-1,20*sizeof(int));
    PrintA();

    //二維對象a[1]重載[]為一維指針(ptr + i * col)
    //一維[]為指針 (地址) 取值
    memset(a[1][1],0,5*sizeof(int)); //a[1][1]
    PrintA();

    for( int i = 0; i < 3; ++ i )
        for( int j = 0; j < 2; ++j )
            for( int k = 0; k < 2; ++k )
                b[i][j][k] = 10.0/(i+j+k+1);
    PrintB();
    int n = a[0][1][2]; //第0層第1行第2列的值
    double f = b[0][1][1];
    cout << "****" << endl;
    cout << n << "," << f << endl;

    return 0;
}
View Code

  037:函數對象的過濾器

#include <iostream>
#include <vector>
using namespace std;

//vector元素為對象的,對象要有比較函數
struct A
{
    int v;
    A() { }
    A(int n):v(n) { };
    bool operator<(const A & a) const //比較函數
    {
        return v < a.v;
    }
};

template<class T>
struct FilterClass
{   // 模板類的函數對象  FilterClass<int>(m,n)
    T low;
    T high;
    FilterClass(int m,int n):low(m),high(n) {}
    bool operator()(const T & rhs) //重載了()運算符,對象為函數對象
    {
        if( low < rhs && rhs < high) //選取在 low 至 high 之間
            return true;             //不包含 low high
        return false;
    }
};

template <class T>
void Print(T s,T e)
{
    for(; s!=e; ++s)
        cout << *s << ",";
    cout << endl;
}

template <class T1, class T2,class T3>
T2 Filter( T1 s,T1 e, T2 s2, T3 op)
{
    for(; s != e; ++s)
    {
        if( op(*s) ) //函數對象,參數是T1類型的*s //bool operator()(const T & rhs)
        {             //本題為迭代器取值
            * s2 = * s; // 在函數對象的限定范圍之內的復制
            ++s2;
        }
    }
    return s2;
}

ostream & operator <<(ostream & o,A & a)
{
    o << a.v;
    return o;
}

vector<int> ia;
vector<A> aa;

int main()
{
    int m,n;
    while(cin >> m >> n)
    {
        ia.clear();
        aa.clear();

        int k,tmp;
        cin >> k;
        for(int i = 0; i < k; ++i)
        {
            cin >> tmp;
            ia.push_back(tmp);
            aa.push_back(tmp);
        }

        vector<int> ib(k);
        vector<A> ab(k);
        //FilterClass<int>(m,n) 是對象//ia.begin() 是 vector<int>::iterator
        vector<int>::iterator p =  Filter(ia.begin(),ia.end(),ib.begin(),FilterClass<int>(m,n));
        Print(ib.begin(),p); //p --> 返回的迭代器ib.end()
        vector<A>::iterator pp = Filter(aa.begin(),aa.end(),ab.begin(),FilterClass<A>(m,n));
        Print(ab.begin(),pp);

    }
    return 0;
}
View Code

  038:白給的list排序

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
int main()
{
    double a[] = {1.2,3.4,9.8,7.3,2.6};
    list<double> lst(a,a+5);
    lst.sort(
        greater<double>() //降序
        //less<double>()  //升序
    );

    for(list<double>::iterator i  = lst.begin(); i != lst.end(); ++i)
        cout << * i << "," ;
    return 0;
}
/* 
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct greater : public binary_function<_Tp, _Tp, bool>
{
    bool
    operator()(const _Tp& __x, const _Tp& __y) const
    {
        return __x > __y;
    }
}; */

/* 
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
    bool
    operator()(const _Tp& __x, const _Tp& __y) const
    {
        return __x < __y;
    }
}; */
View Code

  039:我自己的 ostream_iterator

#include <iostream>
#include <list>
#include <string>
using namespace std;

//遍歷輸出
template <class T1,class T2>
void Copy(T1 s,T1 e, T2 x) //output迭代器x++
{    //list迭代器T1
    for(; s != e; ++s,++x) //輸出
        *x = *s; //迭代器對象賦值
}

 
template<class T>
class myostream_iteraotr
{
private:
    ostream & os; //cout
    string s;     //"," 或 "--"
    T val;          //* 賦值
public:
    myostream_iteraotr(ostream & os, const string &s) :os(os), s(s) { }
    
    T & operator*()     // * 運算符重載 返回T類型引用T& 左值
    {
        return val;
    }
    
    myostream_iteraotr& operator++()  //++ 運算符重載 實現輸出
    {
        os<< val << s;  //cout << val << ","
        return *this;
    }  
};


int main()
{    const int SIZE = 5;
    int a[SIZE] = {5,21,14,2,3};
    double b[SIZE] = { 1.4, 5.56,3.2,98.3,3.3};
    list<int> lst(a,a+SIZE);
    
    myostream_iteraotr<int> output(cout,",");
    Copy( lst.begin(),lst.end(),output); //output迭代器++ 輸出
    
    cout << endl;
    myostream_iteraotr<double> output2(cout,"--");
    Copy(b,b+SIZE,output2);
    return 0;
}
View Code

  040:List

#include <list>  
#include <iostream>  
#include <map>  
#include <fstream>  
using namespace std;   

/* 
寫一個程序完成以下命令:
new id ——新建一個指定編號為id的序列(id<10000)
add id num——向編號為id的序列加入整數num
merge id1 id2——合並序列id1和id2中的數,並將id2清空
unique id——去掉序列id中重復的元素
out id ——從小到大輸出編號為id的序列中的元素,以空格隔開
 */
/*    
16
new 1
new 2
add 1 1
add 1 2
add 1 3
add 2 1  
add 2 2
add 2 3
add 2 4
out 1
out 2
merge 1 2
out 1
out 2
unique 1
out 1 
*/
int main()  
{     
    int id1, id2, num, n;  
    char str[10]; 
    //實現一個id對應多個值,map是一個鍵對應一個值,那么map的值應該是一個list
    //每個STL中的類都有value_type,就是stl容器 盛裝的數據的 數據類型
    //ml容器的 value_type 就是 ( int, list<int> )
    map< int, list<int> > ml; // new id 新建一個指定編號為id的序列(id<10000)
    list<int>::iterator i;    //list<int> 迭代器 
    
    cin >> n;      //16
    while (n--)  
    {  
        cin >> str; //new add out merge unique  
        switch (str[0]) //取字符串的第一個字符  
        {  
        case 'n':  //new
            cin >> id1;  
            //插入一條數據,id1是int,list<int>() 是 list<int> 的一個對象
            //ml.insert( map< int, list<int> >::value_type( id1, list<int>() ) );  
            ml[id1] = list<int>(); //簡寫!插入一條數據,id1是鍵,list<int>()是值
            break;  
        case 'a':  //add
            cin >> id1 >> num;
            //ml[id1] 取id1鍵的值list<int> 對象,ml[id1].push_back(num)把num插入到該對象
            ml[id1].push_back(num);  
            break;  
        case 'm':  //merge 合並
            cin >> id1 >> id2;  
            ml[id1].merge(ml[id2]); //兩個list合並 
            break;  
        case 'u':  //unique 去重
            cin >> id1;  
            ml[id1].sort();         //list先排序
            ml[id1].unique();         //list 去重
            break;  
        case 'o':  //out
            cin >> id1;  
            ml[id1].sort(); 
            //編號為id1的list遍歷
            for (i = ml[id1].begin(); i != ml[id1].end(); i++)  
            {  
                cout << *i << " ";  
            }  
            cout << endl;  
            break;  
        }  
    }  
    return 0;  
}  
View Code

  041:Set

/* 
現有一整數集(允許有重復元素),初始為空。

我們定義如下操作:

add x 把x加入集合
del x 把集合中所有與x相等的元素刪除
ask x 對集合中元素x的情況詢問

對每種操作,我們要求進行如下輸出。

add 輸出操作后集合中x的個數
del 輸出操作前集合中x的個數
ask 先輸出0或1表示x是否曾被加入集合(0表示不曾加入),
再輸出當前集合中x的個數,中間用空格格開。 */

/* 
7
add 1---1     //加入1   有一個1
add 1---2     //再加入1 有二個1
ask 1---1 2   //問是否加入過1 還有幾個 2 
ask 2---0 0   //問是否加入過2 還有幾個 0
del 2---0     //刪除幾個 2
del 1---2     //刪除幾個 1
ask 1---1 0   //是否加入過1 還有幾個 0
*/

#include <iostream>  
#include <set>  
#include <string>  
using namespace std;  

int main()  
{  
    multiset<int> ms;  //允許有重復元素,初始為空 
    set<int> s;        //不允許重復元素 記錄曾經加入過
    
    int n, num;  
    string str; 
    
    cin >> n;  
    while (n--)  
    {  
        cin >> str;  
        if (str == "add")  
        {  
            cin >> num;  
            s.insert(num);  
            ms.insert(num);  
            cout << ms.count(num) << endl;  //插入集合中元素為x的個數
        }  
        else if (str == "ask")  
        {  
            cin >> num;  
            if ( s.count(num) )  //對集合中元素x的情況詢問,是否曾被加入
                cout << "1" << " ";  
            else  
                cout << "0" << " ";  
            cout << ms.count(num) << endl; //還有幾個 
        }  
        else if (str == "del")  
        {  
            cin >> num;  
            cout << ms.count(num) << endl; //刪除幾個 
            ms.erase(num);  //把集合中所有與x相等的元素刪除
        }  
    }  
  
    return 0;  
}  
View Code

  042:熱血格斗場

#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<int,int> member;    //會員 
    member[1000000000] = 1; //facer id為1,實力值1000000000

    int n;
    cin >> n;

    while (n--)
    {
        int id, power;
        cin >> id >> power;
        
        map<int,int>::iterator it = member.upper_bound( power ); //upper_bound() 查找大於目標值的第一個元素
        //每一個新隊員都會選擇與他實力最為接近的人比賽
        int id_tmp = it->second;  //第一個
        int tmp1 = abs( it->first - power );     //tmp1 < tmp2 絕對值小的
        
        if(it != member.begin())  //不是第一個
        {      
            it--; //前面的一個元素
            int tmp2 = abs( it->first - power ); //tmp1 >=tmp2  選擇比他弱的那個
            if( tmp1 >= tmp2 ) //絕對值小的
            {
                id_tmp = it->second;   //更新 id_tmp 
            }          
        }
        
        cout << id << " " << id_tmp << endl;
        
        member[power] = id;
    }
    return 0;
}
View Code

  043:冷血格斗場

#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<int,int> member;    //會員
    member[1000000000] = 1; //facer id為1,實力值1000000000

    int n;
    cin >> n;

    while (n--)
    {
        int id, power;
        cin >> id >> power;

        map<int,int>::iterator it = member.upper_bound( power ); //upper_bound() 查找大於目標值的第一個元素
        //每一個新隊員都會選擇與他實力最為接近的人比賽

        int id_tmp = it->second;  //是第一個
        int power_tmp = it->first;
        
        if(it != member.begin())  //不是第一個
        {        
            it--;
            if( abs( it->first - power ) < abs( power_tmp - power ) )
            {
                id_tmp = it->second; //絕對值小的
            }
            else if( abs( it->first - power ) == abs( power_tmp - power ) )
            {
                id_tmp = min( id_tmp, it->second ); //實力相同,id小的
            }                            
        }
        cout << id << " " << id_tmp << endl;

        if( member[power] ) //避免存儲多個實力值相同的id
        {
            id = min( member[power],id );
        }
        member[power] = id;            
    }
    return 0;
}
View Code

  044:編程填空:數據庫內的學生信息

#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;

template <class T>
struct myGreater //MyMultimap的Pred的默認類型
{
    bool operator() (const T& x, const T& y) const
    {
        return x > y;
    }
    /* typedef T first_argument_type;
    typedef T second_argument_type;
    typedef bool result_type; */
};

template<typename K, typename V, class Pred = myGreater<K> >
class MyMultimap
{
public:
    typedef std::multimap<K, V, Pred>  myType;
    typedef typename std::multimap<K, V>::iterator iterator;
    myType myMap;
    //插入的是鍵值對 make_pair( s[i].score,s[i].name )
    void insert(std::pair<K, V> p)//insert
    {
        myMap.insert(p);
    }
    iterator find(K k)            //find
    {
        return myMap.find(k);
    }
    iterator begin()              //begin
    {
        return myMap.begin();
    }
    iterator end()                //end
    {
        return myMap.end();
    }
    //把所有名為"Tom"的學生的成績都設置為78
    void Set(K k, V v)            //Set
    {   /* equal_range函數用於在序列中表示一個數值的第一次出現與最后一次出現的后一位 */
        iterator starting = myMap.equal_range(k).first; //第一次出現
        iterator ending = myMap.equal_range(k).second;  //最后一次出現的后一位    
        while (starting != ending)
        {
            starting->second = v;
            starting++;
        }
    }
    void clear()                 //clear
    {
        myMap.clear();
    }
};

template<typename T1, typename T2>
std::ostream& operator << (std::ostream& o, std::pair<const T1, T2> p)
{   //迭代器指向的是鍵值對,第二個參數不是 const
    std::cout << "(" << p.first << "," << p.second << ")";
    return o;
}

struct Student
{
    string name;
    int score;
};

template <class T>
void Print(T first,T last)
{
    for(; first!= last; ++ first)
        cout << * first << ",";  //迭代器指向的是鍵值對 重載 << 運算符
    cout << endl;
}

int main()
{

    Student s[] = { {"Tom",80},{"Jack",70},
        {"Jone",90},{"Tom",70},{"Alice",100}
    };

    MyMultimap<string,int> mp;            //名字為鍵,成績為值
    for(int i = 0; i<5; ++ i)
        mp.insert(make_pair(s[i].name,s[i].score));
    Print(mp.begin(),mp.end()); //按姓名從大到小輸出

    mp.Set("Tom",78); //把所有名為"Tom"的學生的成績都設置為78
    Print(mp.begin(),mp.end());

    MyMultimap<int,string,less<int> > mp2; //成績為鍵,名字為值// less<int> // less是stl里面的一個函數對象
    for(int i = 0; i<5; ++ i)
        mp2.insert(make_pair(s[i].score,s[i].name));

    Print(mp2.begin(),mp2.end()); //按成績從小到大輸出 
    mp2.Set(70,"Error");          //把所有成績為70的學生,名字都改為"Error"
    Print(mp2.begin(),mp2.end());

    cout << "******" << endl;

    mp.clear(); //clear()函數用於從map容器中刪除所有元素,從而使其大小保持為0

    string name;
    string cmd;
    int score;
    while(cin >> cmd )
    {
        if( cmd == "A")
        {
            cin >> name >> score;
            if(mp.find(name) != mp.end() )
            {
                cout << "erroe" << endl;
            }
            mp.insert(make_pair(name,score));
        }
        else if(cmd == "Q")
        {
            cin >> name;
            MyMultimap<string,int>::iterator p = mp.find(name);
            if( p!= mp.end())
            {
                cout << p->second << endl;
            }
            else
            {
                cout << "Not Found" << endl;
            }
        }
    }
    return 0;
}
View Code

  045:魔獸世界三(開戰)

  封閉類:

  一個類的對象是其他類的對象,這個對象叫成員對象有成員對象的類叫封閉類,任何生成封閉類對象的語句,都要讓編譯器明白,對象中的成員對象,是如何初始化的:通過封閉類的構造函數的初始化列表,成員對象初始化列表中的參數可以是任意復雜的表達式,可以包括函數,變量,只要表達式中的函數或變量有定義就行

  封閉類對象生成時,先執行所有對象成員的構造函數,然后才執行封閉類的構造函數,對象成員的構造函數調用次序和對象成員在類中的說明次序一致,與它們在成員初始化列表中出現的次序無關

  類A擁有類B的代碼說明:

#include<iostream>
using namespace std;

//1、類前置聲明 只是讓類A知道類B,但不知道類B的成員,比如類B的成員函數print()
//所以類A的成員函數PrintB(),要在類B整體聲明之后、類外定義實現
class B; 
//類A用到了類B,類B在類A下面聲明,需要前置聲明類B
//類A整體聲明
class A  
{
    int i;
public:
    A(int i):i(i) { }
    void PrintB(B *b);  
    //類A成員函數用到了類B,成員函數要在類B聲明之下定義實現
};

//類B整體聲明
class B
{
    int j;
public:
    B(int j):j(j) { }
    void print(); //聲明了print()
};

//2、在類B聲明之后、在類外實現
//這里知道了類B的成員函數print(),因為上面B類聲明了print()
void A:: PrintB(B *b)
{
    b->print();
}
void B::print()
{
    cout << "B = " << j << endl;
}

int main()
{    
    A a(111);
    B b(222);
    a.PrintB(&b);
    return 0;
}
View Code

  this指針: 

  this指針其作用,就是指向成員函數所作用的對象,靜態成員函數中不能使用this指針,因為靜態成員函數是屬於類的,不屬於任何對象

#include<iostream>
using namespace std;
class A{
    int i;
public:
    void Hello(){ cout << "Hello" << endl; }
    // void Hello(A* this) { cout << "Hello" << endl; }
};
int main()
{
    A* p = NULL;
    p -> Hello();  //輸出Hello
    // Hello(p);
    return 0;
}
View Code
#include<iostream>
using namespace std;
class A{
    int i;
public:
    void Hello(){ cout << i << "Hello" << endl; }
    // void Hello(A* this) { cout << this->i << "Hello" << endl; }
    //this->i !!  this為NULL,出錯
};
int main()
{
    A* p = NULL;
    p -> Hello();  
    // Hello(p);
    return 0;
}
View Code

  類A擁有類B、類B擁有類A的代碼說明:

#include<iostream>
using namespace std;

//1、類前置聲明 只是讓類A知道類B,但不知道類B的成員,比如類B的成員函數print()
//所以類A的成員函數PrintB(),要在類B整體聲明之后、類外定義實現
class B; 
//類A用到了類B,類B在類A下面聲明,需要前置聲明類B
//類A整體聲明
class A  
{
    int i;
public:
    A(int i):i(i) { }
    int getI() { return i; }
    void PrintB(B *b);               // !!!A中有B
    //類A成員函數用到了類B,成員函數要在類B聲明之下定義實現
};

//類B整體聲明
class B
{
    int j;
public:
    B(int j):j(j) { }
    void print(A* a); //聲明了print()  //!!!B中有A
};

//2、在類B聲明之后、在類外實現
//這里知道了類B的成員函數print(),因為上面B類聲明了print()
void A:: PrintB(B *b)
{
    b->print(this); //this指針 
}
void B::print(A* a)
{
    cout << "A = " << a->getI() << endl;
}

int main()
{    
    A a(111);
    B b(222);
    a.PrintB(&b);
    return 0;
}
View Code

  第一部分 面向對象的編程

  面向對象編程(Object-oriented programming , OOP),基於三個概念:數據抽象、繼承 和 動態綁定

  動態綁定使編譯器能夠在運行時決定是使用基類中定義的函數還是派生類中定義的函數,在C++中,通過基類的引用或指針調用虛函數時,發生動態綁定,調用的虛函數在運行時確定,被調用的函數是引用或指針所指向對象的實際類型所定義

  在C++中基類必須指出希望派生類重新定義哪些函數,定義為virtual的函數即虛函數,不是基類期待派生類重新定義的,不能定義為虛函數

#include <iostream>
using namespace std;

class Base{
    int base_num;
public:
    Base( int number ): base_num(number){}
    virtual int getNum(){  //虛函數,期望派生類重定義
        return base_num;
    }
};

class Derived:public Base
{
    int derived_num;
public:
    Derived( int num1, int num2 ):Base(num1), derived_num(num2){}
    virtual int getNum(){ //重定義的函數
        return derived_num;
    }
};

void printNum(Base &b){ //基類的引用
    cout << b.getNum() << endl;
}

void printNum(const Base &b){ //臨時對象是右值,可以用const綁定
    cout << "臨時對象是右值,可以用const綁定" << endl;
}

/* void printNum(const Base &b){   //基類的引用是const
    cout << b.getNum() << endl; //調用了非const的函數不可以
} */


int main() 
{
    Derived d(80,90);
    printNum(d); //傳的是派生類的對象
    printNum(Derived(50,60)); //臨時對象是右值,可以用const綁定
    
    return 0;
}
View Code

  第二部分 泛型編程

  模板機制,以及標准模板庫STL

  標准模板庫(Standard Template Library)就是一些常用數據結構和算法模板的集合,有了STL,不必再寫太多的標准數據結構和算法,並且可以獲得非常高的性能  

  STL六大部件:容器(Containers)、分配器(Allocators)、算法(Alogrithms)、迭代器(Iterators)、仿函數(Functors,頭文件為<functional>)、適配器(轉換器)(Adapters)

  

  一、容器(Containers)

  容器的定義:

  在數據存儲上,有一種對象類型,它可以持有其它對象或指向其它對象的指針,這種對象類型就叫做容器。很簡單,容器就是保存其它對象的對象,當然這是一個朴素的理解,這種“對象”還包含了一系列處理“其它對象”的方法。容器即物之所在,容器是STL的核心部件之一,是迭代器的依附,是算法作用的目標 

  容器的種類:

  順序容器:是一種各元素之間有順序關系的線性表,是一種線性結構的可序群集。順序性容器中的每個元素均有固定的位置,除非用刪除或插入的操作改變這個位置。順序容器的元素排列次序與元素值無關,而是由元素添加到容器里的次序決定。順序容器包括:vector(向量)、list(列表)、deque(隊列)
  關聯容器:關聯式容器是非線性的樹結構,更准確的說是二叉樹結構。各元素之間沒有嚴格的物理上的順序關系,也就是說元素在容器中並沒有保存元素置入容器時的邏輯順序。但是關聯式容器提供了另一種根據元素特點排序的功能,這樣迭代器就能根據元素的特點“順序地”獲取元素。元素是有序的集合,默認在插入的時候按升序排列。關聯容器包括:map(集合)、set(映射)、multimap(多重集合)、multiset(多重映射)
  容器適配器:本質上,適配器是使一種不同的行為類似於另一事物的行為的一種機制。容器適配器讓一種已存在的容器類型采用另一種不同的抽象類型的工作方式實現。適配器是容器的接口,它本身不能直接保存元素,它保存元素的機制是調用另一種順序容器去實現,即可以把適配器看作“它保存一個容器,這個容器再保存所有元素”。STL 中包含三種適配器:棧stack 、隊列queue 和優先級隊列priority_queue

  容器類自動申請和釋放內存,因此無需new和delete操作。

  不同容器的使用方法:

  1、set  有序性,鍵值為對象,要求有比較函數

/*
 * 維護平面點

一開始平面上一個點都沒有
每次可以插入一個點,刪除一個已經存在的點,或者按照x 或y 來查詢一個存在的點
保證任何時候任意兩個點一定是一個點嚴格在另一個點的右下方
即兩點(x1, y1), (x2, y2),必定有x1 > x2 且y1 < y2 ,或者x1 < x2 且y1 > y2

輸入:
A 3 5
A 4 2
Qx 4
R 4 2
A 4 3
Qy 3

輸入數據的每一行,格式為以下之一:
A x y
R x y
Qx x
Qy y
其中 x 與 y 都是 0 到 10^9 之間的整數
A x y 表示插入點 (x, y)
R x y 表示刪除點 (x, y),保證存在
Qx x 表示在當前所有點中,找到第一維為x的點,輸出其第二維的值,保證存在
Qy y 表示在當前所有點中,找到第二維為y的點,輸出其第一維的值,保證存在
總共操作數不超過100000
輸出:
2
4
對於每一個 Qx 和 Qy 操作,輸出一行表示對應的答案
*/


#include <set>
#include <iostream>
#include <string>
using namespace std;
// 在此處補充你的代碼
struct myComp {
    bool operator()(const pair<int, int> &a, const pair<int, int> &b) {
        if (a.first > 0 && a.second > 0 && b.first > 0 && b.second > 0) {
            return a.first > b.first; //  x 值大小排序
        } else if (a.first < 0 || b.first < 0) {
            return a.second < b.second;  // y 值大小排序
        } else if (a.second < 0 || b.second < 0) {
            return a.first > b.first;  // x 值大小排序
        }
        return true;
    }

};
int main() {
    string cmd;
    set<pair<int, int>, myComp> S; // 模板類型 myComp
    while (cin >> cmd) {
        if (cmd == "A") {
            int x, y;
            cin >> x >> y;
            S.insert(make_pair(x, y)); //插入一個點
        } else if (cmd == "Qx") {
            int x;
            cin >> x;
            cout << S.lower_bound( make_pair(x, -1) )->second << endl;//返回大於等於x的第一個位置的迭代器
        } else if (cmd == "Qy") {
            int y;
            cin >> y;
            cout << S.lower_bound(make_pair(-1, y))->first << endl; //返回大於等於y的第一個位置的迭代器
        } else {
            int x, y;
            cin >> x >> y;
            S.erase(make_pair(x, y)); //刪除一個點
        }
    }
    return 0;
}
View Code

  set嵌套及比較函數使用

#include <iostream>
#include <set>
using namespace std;

struct weapon
{
    int number;
    int power;
    weapon(int n,int p):number(n),power(p) //構造
    {
        
    }
    bool operator < (const weapon &w) const/* 鍵比較大小 const 函數(常函數)*/
    {
        if( number == w.number ) //里層同類有序
            return power < w.power;
        return number < w.number;
    } 
    /* friend bool operator < (const weapon& w1,const weapon& w2)//比較函數 ( 友元 )
    {
        if( w1.number == w2.number ) //里層同類有序
            return w1.power < w2.power;
        return w1.number < w2.number; //外層不同類有序
    } */
}sword(0,100),bomb(1,105),arrow(2,103),bomb2(1,99);

int main()
{    
    set<set<weapon> > wset;    
    set<weapon> w1,w2,w3;
    
    w1.insert(sword);
    w2.insert(bomb);
    w2.insert(bomb2);
    w3.insert(arrow);

    wset.insert(w2);
    wset.insert(w3);
    wset.insert(w1);
    
    set<set<weapon> > ::iterator it = wset.begin(); 
    int n = wset.size();
    while(n--)
    {
        set<weapon > ::iterator wit = it->begin(); //(*it).begin();
        int cnt = it->size();
        while(cnt--)
        {
            cout << "power = " << wit->power << "\t,  num = " << wit -> number << endl; 
            wit++;
        }
        cout << "---------------------------" << endl;        
        it++;
    }
    
    return 0;
}
View Code

  武器編號小的在前,編號相同的,攻擊低的在前的代碼實現:

#include <iostream>
#include <set>
using namespace std;

struct weapon
{
    int number;
    int power;
    weapon(int n,int p):number(n),power(p)
    {
        
    }
    bool operator < (const weapon &w) const
    {
        if( number == w.number ) 
            return power < w.power;
        return number < w.number;
    } 

}sword(0,100),bomb(1,105),arrow(2,103),bomb2(1,99),arrow2(2,50);

int main()
{    
    set<weapon > wset;    
    
    //wset.insert(sword);
    wset.insert(bomb);
    wset.insert(bomb2);
    wset.insert(arrow);
    wset.insert(arrow2);

    set<weapon > ::iterator it = wset.begin(); 
    int n = wset.size();
    while(n--)
    {
        cout << "power = " << it->power << "\t,  num = " << it -> number << endl; 
        cout << "---------------------------" << endl;        
        it++;
    }
    
    return 0;
}
View Code

  每個武器的編號、攻擊力及這種武器的數量,有序:武器編號小的在前,編號相同的,攻擊低的在前,enum、struct、pair、static、set

#include <iostream>
#include <set>
using namespace std;

enum { SWORD, BOMB, ARROW, WEAPON_SIZE } ;

struct weapon
{
    pair<int,int> number_power; //編號及個數
    static int count[WEAPON_SIZE];
    
    weapon(int n,int p):number_power( n,p )
    {
        count[number_power.first]++;
    }
    bool operator < (const weapon &w) const
    {
        if( number_power.first == w.number_power.first ) 
            return number_power.second < w.number_power.second;
        return number_power.first < w.number_power.first;
    } 

}sword( SWORD,100 ), 
    bomb( BOMB,105 ),
    arrow( ARROW,103 ),
    bomb2( BOMB,99 ),
    arrow2( ARROW,50 )    
;

int weapon::count[WEAPON_SIZE] = { 0 };

int main()
{    
    set<weapon > wset;    
    
    //wset.insert(sword);
    wset.insert(bomb);
    wset.insert(bomb2);
    wset.insert(arrow);
    wset.insert(arrow2);

    set<weapon > ::iterator it = wset.begin();
    
    /* int n = wset.size();
    while(n--)
    {
        cout << "power = " << it->number_power.second 
            << "\t,  num = " << it ->number_power.first << endl; 
        cout << "count = " << weapon::count[ it ->number_power.first ] << endl;
        
        cout << "---------------------------" << endl;        
        it++;
    }     */
    int n = it ->number_power.first;
    while( it ->number_power.first == n )
    {
        cout << "power = " << it->number_power.second 
            << "\t,  num = " << it ->number_power.first << endl; 
        cout << "count = " << weapon::count[ it ->number_power.first ] << endl;
        
        cout << "---------------------------" << endl;        
        it++;
    }    
    
    return 0;
}
View Code

  c++語言中,multiset 是 <set> 庫中一個非常有用的類型,它可以看成一個序列,插入一個數,刪除一個數都能夠在O(logn)的時間內完成,而且他能時刻保證序列中的數是有序的,而且序列中可以存在重復的數

/*
    輸入n個整數,輸出整數數列中大小排名前k的偶數
    測試用例:
    2
    9 4
    1 2 4 3 6 6 7 8 9
    3 2
    18 16 14
 */

#include <iostream>
#include <set>

using namespace std;

class MyQueue
{
    int k;  //創建對象時,k表示前k個偶數整數
    multiset < int, greater<int> > que; //multiset容器對象 元素有序且可以重復
public:

    MyQueue(int k):k(k) {}

    //容器插入對象
    friend istream & operator>>(istream&is, MyQueue &a) //對象輸入 重載 >> 運算符
    {
        int num;
        is >> num;
        if (num % 2 == 0)
        {
            a.que.insert(num); //是偶數插入
        }
        return is;
    }

    //從容器輸出對象
    friend ostream & operator <<(ostream&os, MyQueue &a) //對象輸出 重載 << 運算符
    {
        multiset<int>::iterator p = a.que.begin(); //迭代器
        int count = 0;
        for (; count < a.k; p++)
        {
            if (count){
                os << " ";
            }            
            os << *p ; //輸出元素
            count++;   //記錄輸出元素個數
        }
        return os;
    }
};

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n, k;
        cin >> n >> k;
        MyQueue q(k);
        for (int i = 0; i < n; ++i)
            cin >> q; //利用>>運算符重載 輸入整數(插入到對象 q 的 multiset 容器中)
        cout<<q;
        cout << endl;
    }

    return 0;
}
View Code

  multiset 容器,矩形類對象大小排序,默認 <運算符重載 (< 雙目運算符,友元函數 ), 模板類型(友元類),函數對象,()運算符重載,注:何時使用友元當你想要用普通函數非本類的成員函數調用本類的私有成員時

/* 矩形排序
給定一系列邊長已知的矩形,輸出對矩形進行兩種排序的結果。
在第一種排序中,先按矩形的面積從大到小排序;若兩個矩形的面積相同,則周長大的排在前。
在第二種排序中,先按矩形的周長從小到大排序;若兩個矩形的周長相同,則面積小的排在前。
輸入:
6
3 8
4 6
10 2
6 6
4 8
3 6
第一行是一個整數n,表示輸入的矩形個數。
接下來n行表示了n個矩形。每行有兩個整數a與b,表示該矩形的長與寬。
輸出:
36 24
32 24
24 22
24 20
20 24
18 18

18 18
24 20
24 22
20 24
32 24
36 24 */

#include <iostream>
#include <set>
using namespace std;
// 在此處補充你的代碼
class Rectangle
{
    int length, width, area, perimeter; //長、寬、面積、直徑
public:    
    friend class Comp;  //友元類 可以處理 Rectangle 類的數據成員
    Rectangle(int _length, int _width) : length(_length), width(_width) //構造函數
    {
        area = length * width;
        perimeter = 2 * (length + width);
    }
    //友元函數 比較對象大小
    friend bool operator<(const Rectangle &rec1, const Rectangle &rec2) //  < 運算符重載 
    {
        if (rec1.area == rec2.area)   //面積相等 直徑大的在前
            return rec1.perimeter > rec2.perimeter;
        return rec1.area > rec2.area; //面積大的在前
    }
    //輸出對象
    friend ostream &operator<<(ostream &os, const Rectangle &obj) // 友元函數 << 運算符重載 輸出面積及直徑
    {
        cout << obj.area << ' ' << obj.perimeter;
        return os;
    }
};

class Comp
{
public:
    bool operator()(const Rectangle &rec1, const Rectangle &rec2) //比較對象大小
    {
        if (rec1.perimeter == rec2.perimeter) //直徑相等 面積小的在前
            return rec1.area < rec2.area;
        return rec1.perimeter < rec2.perimeter; //直徑小的在前
    }
};

int main() 
{
    multiset<Rectangle> m1;   //默認 < 運算符重載 友元函數
    multiset<Rectangle, Comp> m2; //模板 Comp類型 函數對象(臨時對象) Rectangle類的友元類 < 運算符重載 
    int n, a, b;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a >> b;
        m1.insert(Rectangle(a, b));
        m2.insert(Rectangle(a, b));
    }
    for (multiset<Rectangle>::iterator it = m1.begin(); it != m1.end(); it++) {
        cout << *it << endl;
    }
    cout << endl;
    for (multiset<Rectangle>::iterator it = m2.begin(); it != m2.end(); it++) {
        cout << *it << endl;
    }
    return 0;
}
View Code

  2、<vector> 容器的 for_each(iterator,iterator,pointer)(第三個參數:pointer是指向函數的指針:lambda表達式、全局函數 或  函數對象-->臨時對象)

  臨時對象,就是一種無名對象(unamed objects),臨時對象類名之后直接加一對小括號 () 或者大括號 {}(列表初始化),並可指定初值,其意義相當於調用相應的構造函數並且不指定對象名

  函數對象(function object),形式上是一個類實例化的對象,本質上是為了實現某種與函數等價的功能,函數對象的思想是:用類來封裝一個函數功能,然后用這個類實例化不同的函數對象,若一個類重載了運算符(),則該類的對象就成為函數對象    注:重載()運算符,參數沒有限制,比如:bool operator()(int a,int b,int c){...}

/*
    完成以下程序,使得輸入的整數x,以及若干正整數,將
大於x的正整數輸出;然后輸入若干字符串,將字符串長度大於x的字符串輸出
    測試用例:
    2
    5 6
    1 3 59 30 2 40
    this is hello please me ha
    1 1
    4
    this
    輸出:
    59,30,40,
    please,
    4,
    this,
 */

#include <algorithm> //for_each 頭文件
#include <iostream>
#include <vector>

using namespace std;


class Printer
{
    int size;

public:
    Printer(int x) : size(x) {}

    void operator()(int x)  //運算符()重載
    {
        if (x > size)
            cout << x << ',';
    }

    void operator()(string str) //運算符()重載
    {
        if (str.size() > size)
            cout << str << ',';
    }
};

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n,x;
        cin >> x >> n;

        vector<int> intVec;
        for(int i = 0; i < n; ++i)
        {
            int y;
            cin >> y;
            intVec.push_back(y);
        }
        for_each(intVec.begin(), intVec.end(), Printer(x)); //Printer(x)是函數對象
        cout << endl;

        vector<string> strVec;
        for(int i = 0; i < n; ++i)
        {
            string str;
            cin >> str;
            strVec.push_back(str);
        }
        for_each(strVec.begin(), strVec.end(), Printer(x));
        cout << endl;
    }
    return 0;
}
View Code

  全局函數

#include <iostream>
#include <vector>
#include <algorithm>  //for_each 

using namespace std;

//全局函數
void printElem(int elem, const char* prefix)
{
    cout << prefix << elem << endl;
}

int main()
{
    int ia[] = {1, 2, 3};
    vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
    for_each(ivec.begin(), ivec.end(), bind2nd(ptr_fun(printElem), "Element:"));
    
    return 0;
}
View Code

  lambda表達式:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    int i = 3;
    vector<char*> v;
    
    while(i--)
    {        
        char* p = new char(128); 
        cin >> p;
        v.push_back(p); 
    }
    
    //遍歷的3種方法
    for_each( v.begin(),v.end(),[=](char*str){ cout << str << endl; } );
    
    /* for(vector<char*>::iterator it= v.begin();it!=v.end();++it)
    {
        cout << (*it) << endl;
    } */
    
    /* for( char*str:v ){
        cout << str << endl;
    } */
    
    return 0;
}
View Code

  3、<list> 容器的 sort 參數:< 運算符重載,函數對象(重載 () 運算符),全局函數,<list>容器的 for_each 的參數為全局函數

/*
三生三世

測試用例:3代表3個電視劇,以下是 每個電視劇的劇名 及 演員陣容、劇情和演技的分數
3
In the Name of People
98 97 99
Life After Life, Blooms Over Blooms
99 82 73
Ming Dynasty: 1566
97 100 100
輸出:按分數(分別為演員陣容、劇情和演技的分數)從大到小排序3次,並按排序輸出劇名

*/
#include <iostream>   //string
#include <list>       //list
#include <algorithm>  // sort
using namespace std;

class TV_Drama {
public:
    char name[100]; //電視劇
    int actor;  //演員陣容評分
    int story;  //劇情評分
    int acting_skill; //演技評分
    // 在此處補充你的代碼
    TV_Drama(string _name, int _actor, int _story, int _acting_skill) :
            actor(_actor), story(_story), acting_skill(_acting_skill) {
        _name.copy(name, _name.size(), 0); //string類的函數
        name[_name.size()] = 0; //字符串結束符     name 電視劇劇名
    }
    bool operator <(const TV_Drama &obj) { //對象比較,重載比較運算符  <
        return actor > obj.actor;   //從高到低排序
    }
};


void Printer(const TV_Drama &obj) { //全局函數
    cout << obj.name << ';';
    //cout <<"--" << obj.actor << "--" << obj.story << "--" << obj.acting_skill<< endl;
}
bool comparator_1(const TV_Drama &o1, const TV_Drama &o2) { //全局函數
    return o1.story > o2.story;  //從高到低排序
}

class comparator_2 { //函數對象 ,重載了小括號 () 運算符
public:
    bool operator()(const TV_Drama &o1, const TV_Drama &o2) {
        return o1.acting_skill > o2.acting_skill;   //從高到低排序
    }
};

int main() {
    list<TV_Drama> lst;  //對象容器
    int n;
    cin >> n;
    char _name[100];
    int _actor, _story, _acting_skill;
    for (int i = 0; i < n; i++) {
        cin.ignore();  //cin.ignore()函數用於忽略或清除輸入緩沖區中的一個或多個字符
        cin.getline(_name, 100);
        cin >> _actor >> _story >> _acting_skill;
        lst.push_back(TV_Drama(_name, _actor, _story, _acting_skill));
    }

    lst.sort(); //無參 默認對象從小到大,重載 < 運算符改為 從大到小
    for_each(lst.begin(), lst.end(), Printer);
    cout << endl;

    lst.sort(comparator_1);   //全局函數
    for_each(lst.begin(), lst.end(), Printer);
    cout << endl;

    lst.sort(comparator_2()); //函數對象
    for_each(lst.begin(), lst.end(), Printer);
    cout << endl;

    return 0;
}
View Code

  4、<map> 容器,單詞統計

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

/*單詞計數器 */

string& strip(string &str)
{
    for (auto &ch : str)
        ch = tolower(ch);// 轉成小寫
    str.erase( remove_if ( str.begin(), str.end(), static_cast<int(*)(int)>(&ispunct) ), str.end());

    return str;
};

std::map<std::string, std::size_t> count()
{
    std::map<std::string, std::size_t> counts;
    for (string w; cin >> w; ++counts[strip(w)])
        ;
    return counts;
}

void println(std::map<std::string, std::size_t> const &m)
{
    for (auto const &kv : m)
    {
        cout << kv.first << " -- " << kv.second << endl;
    }
}

int main()
{
    println(count()); //count()函數返回的是map容器
    cin.clear();
    return 0;
}
View Code

  5、<queue>    優先隊列priority_queue: 武器編號小的在前,編號相同的,攻擊低的在前的代碼實現:

#include <iostream>
#include <vector>
#include<queue>  //priority_queue
using namespace std;

struct weapon
{
    int number;
    int power;
    weapon(int n,int p):number(n),power(p)
    {
        
    }
    bool operator < (const weapon &w) const
    {
        if( number == w.number ) 
            return power > w.power; //!!!
        return number > w.number;   //!!!
    } 

}sword(0,100),bomb(1,105),arrow(2,103),bomb2(1,99),arrow2(2,50);

int main()
{
    priority_queue<weapon> pqw;
    
    pqw.push(sword);
    pqw.push(bomb);
    pqw.push(arrow);
    pqw.push(bomb2);
    pqw.push(arrow2);
    
    while (!pqw.empty())
    {
        cout << pqw.top().number << "," << pqw.top().power << endl;
        pqw.pop();
    }
        
    return 0;
}
View Code

  二、算法

  <algorithm>中定義了大約80個標准算法,它們操作由一對迭代器定義的(輸入)序列單一迭代器定義的(輸出)序列 

  無論一個STL算法返回什么,它都不會是實參的容器傳遞給STL算法的實參是迭代器算法完全不了解迭代器所指向的數據結構,迭代器的存在主要是為了將算法從它所處理的數據結構上分離出來

  C++標准將算法分成4組:非修改式序列操作、修改式序列操作、排序和相關操作、數值運算

  1、非修改式操作序列

  不修改序列的算法只讀取輸入序列中元素的值,而不會重排序列或是改變元素值,用戶提供給算法的操作一般也不會改變元素值,這些操作通常是謂詞(不會修改實參)
  for_each(),它簡單地對序列中的每個元素執行指定的操作,傳遞給for_each()的操作可能會修改元素,例如:

void increment_all(vector<int>& v)
{
    for_each(v.begin(),v.end(),[](int&x){ ++x; });
}

  2、修改式序列操作

  3、排序和相關操作

  對 vector排序:武器編號小的在前,編號相同的,攻擊低的在前的代碼實現:

#include <iostream>
#include <vector>
#include <algorithm> //sort
using namespace std;

struct weapon
{
    int number;
    int power;
    weapon(int n,int p):number(n),power(p)
    {
        
    }
    bool operator < (const weapon &w) const
    {
        if( number == w.number ) 
            return power < w.power;
        return number < w.number;
    } 

}sword(0,100),bomb(1,105),arrow(2,103),bomb2(1,99),arrow2(2,50);

int main()
{
    vector<weapon> vw;
    
    vw.push_back(sword);
    vw.push_back(bomb);
    vw.push_back(arrow);
    vw.push_back(bomb2);
    vw.push_back(arrow2);

    sort(vw.begin(),vw.end()); //排序算法sort
    
    for(vector<weapon>::iterator it=vw.begin(); it!=vw.end(); ++it)
    {
        cout << it->number << "," << it->power << endl;
    }
    
    return 0;
}
View Code

  4、數值運算

  又見模板,模板,[]運算符重載,成員函數

/*
又見模板

輸入:
1
1 2 3 4 5 6 7 8 9 10
4.2 0.0 3.1 2.7 5.2
Hello , world !

第一行是整數n,表示有n組數據
每組數據有3行
第一行是10個整數
第二行是5個小數
第三行是4個不帶空格的字符串,它們之間用空格分隔

輸出:
3
15.2
Hello,world!
 */
 
#include <iostream>
#include <string>
using namespace std;
// 在此處補充你的代碼

template <typename T, int size>
class A
{
    T *p; //指針
public:
    A(T *obj) : p(new T[size])
    {
        for (int i = 0; i < size; i++)
            p[i] = obj[i];
    }
    T &operator[](int n) { return p[n]; }  //[]運算符重載
    T sum()
    {
        T su = *p;
        for (int i = 1; i < size; i++)
            su += p[i]; //string 類 += 是字符串連接
        return su;
    }
};

int main() 
{    
    int t;
    cin >> t;
    while( t -- ) 
    {     //1、int類型 數組
        int b1[10];
        for(int i = 0;i < 10; ++i)         
            cin >> b1[i];
        
        A<int, 10> a1 = b1;    //構造函數
        cout << a1[2] << endl; // []運算符重載
            
        //2、double類型 數組
        double b2[5] ;
        for(int i = 0;i < 5; ++i)     
            cin >> b2[i];
        
        A<double, 5> a2 = b2; //構造函數
        cout << a2.sum() << endl; // sum成員函數
        
        //3、string類型 數組
        string b3[4] ;
        for(int i = 0;i < 4; ++i)     
            cin >> b3[i];
        
        A<string, 4> a3 = b3; //構造函數  
        cout << a3.sum() << endl; // 調用sum成員函數
    }
    return 0;
}
View Code
 
 
   之前的魔獸世界之三題目及題解代碼:
魔獸世界的西面是紅魔軍的司令部,東面是藍魔軍的司令部。兩個司令部之間是依次排列的若干城市,城市從西向東依次編號為1,2,3 .... N ( N <= 20 )。紅魔軍的司令部算作編號為0的城市,藍魔軍的司令部算作編號為N+1的城市。司令部有生命元,用於制造武士。

兩軍的司令部都會制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五種。每種武士都有編號、生命值、攻擊力這三種屬性。

雙方的武士編號都是從1開始計算。紅方制造出來的第 n 個武士,編號就是n。同樣,藍方制造出來的第 n 個武士,編號也是n。

武士在剛降生的時候有一個初始的生命值,生命值在戰斗中會發生變化,如果生命值減少到0(生命值變為負數時應當做變為0處理),則武士死亡(消失)。

有的武士可以擁有武器。武器有三種,sword, bomb,和arrow,編號分別為0,1,2。

武士降生后就朝對方司令部走,在經過的城市如果遇到敵人(同一時刻每個城市最多只可能有1個藍武士和一個紅武士),就會發生戰斗。每次戰斗只有一方發起主動進攻一次。被攻擊者生命值會減去進攻者的攻擊力值和進攻者手中sword的攻擊力值。被進攻者若沒死,就會發起反擊,被反擊者的生命值要減去反擊者攻擊力值的一半(去尾取整)和反擊者手中sword的攻擊力值。反擊可能致敵人於死地。

如果武士在戰斗中殺死敵人(不論是主動進攻殺死還是反擊殺死),則其司令部會立即向其發送8個生命元作為獎勵,使其生命值增加8。當然前提是司令部得有8個生命元。如果司令部的生命元不足以獎勵所有的武士,則優先獎勵距離敵方司令部近的武士。

如果某武士在某城市的戰斗中殺死了敵人,則該武士的司令部立即取得該城市中所有的生命元。注意,司令部總是先完成全部獎勵工作,然后才開始從各個打了勝仗的城市回收生命元。對於因司令部生命元不足而領不到獎勵的武士,司令部也不會在取得戰利品生命元后為其補發獎勵。

如果一次戰斗的結果是雙方都幸存(平局),則雙方都不能拿走發生戰斗的城市的生命元。

城市可以插旗子,一開始所有城市都沒有旗子。在插紅旗的城市,以及編號為奇數的無旗城市,由紅武士主動發起進攻。在插藍旗的城市,以及編號為偶數的無旗城市,由藍武士主動發起進攻。

當某個城市有連續兩場戰斗都是同一方的武士殺死敵人(兩場戰斗之間如果有若干個戰斗時刻並沒有發生戰斗,則這兩場戰斗仍然算是連續的;但如果中間有平局的戰斗,就不算連續了) ,那么該城市就會插上勝方的旗幟,若原來插着敗方的旗幟,則敗方旗幟落下。旗幟一旦插上,就一直插着,直到被敵人更換。一個城市最多只能插一面旗幟,旗幟沒被敵人更換前,也不會再次插同顏色的旗。

各種武器有其特點:

sword武器的初始攻擊力為擁有它的武士的攻擊力的20%(去尾取整)。但是sword每經過一次戰斗(不論是主動攻擊還是反擊),就會變鈍,攻擊力變為本次戰斗前的80% (去尾取整)。sword攻擊力變為0時,視為武士失去了sword。如果武士降生時得到了一個初始攻擊力為0的sword,則視為武士沒有sword.

arrow有一個攻擊力值R。如果下一步要走到的城市有敵人,那么擁有arrow的武士就會放箭攻擊下一個城市的敵人(不能攻擊對方司令部里的敵人)而不被還擊。arrow使敵人的生命值減少R,若減至小於等於0,則敵人被殺死。arrow使用3次后即被耗盡,武士失去arrow。兩個相鄰的武士可能同時放箭把對方射死。

擁有bomb的武士,在戰斗開始前如果判斷自己將被殺死(不論主動攻擊敵人,或者被敵人主動攻擊都可能導致自己被殺死,而且假設武士可以知道敵人的攻擊力和生命值),那么就會使用bomb和敵人同歸於盡。武士不預測對方是否會使用bomb。

武士使用bomb和敵人同歸於盡的情況下,不算是一場戰斗,雙方都不能拿走城市的生命元,也不影響城市的旗幟。

不同的武士有不同的特點。

dragon可以擁有一件武器。編號為n的dragon降生時即獲得編號為 n%3 的武器。dragon還有“士氣”這個屬性,是個浮點數,其值為它降生后其司令部剩余生命元的數量除以造dragon所需的生命元數量。dragon 在一次在它主動進攻的戰斗結束后,如果還沒有戰死,而且士氣值大於0.8,就會歡呼。dragon每取得一次戰斗的勝利(敵人被殺死),士氣就會增加0.2,每經歷一次未能獲勝的戰斗,士氣值就會減少0.2。士氣增減發生在歡呼之前。

ninja可以擁有兩件武器。編號為n的ninja降生時即獲得編號為 n%3 和 (n+1)%3的武器。ninja 挨打了也從不反擊敵人。

iceman有一件武器。編號為n的iceman降生時即獲得編號為 n%3 的武器。iceman 每前進兩步,在第2步完成的時候,生命值會減少9,攻擊力會增加20。但是若生命值減9后會小於等於0,則生命值不減9,而是變為1。即iceman不會因走多了而死。

lion 有“忠誠度”這個屬性,其初始值等於它降生之后其司令部剩余生命元的數目。每經過一場未能殺死敵人的戰斗,忠誠度就降低K。忠誠度降至0或0以下,則該lion逃離戰場,永遠消失。但是已經到達敵人司令部的lion不會逃跑。Lion在己方司令部可能逃跑。lion 若是戰死,則其戰斗前的生命值就會轉移到對手身上。所謂“戰斗前”,就是每個小時的40分前的一瞬間。

wolf降生時沒有武器,但是在戰斗中如果獲勝(殺死敵人),就會繳獲敵人的武器,但自己已有的武器就不繳獲了。被繳獲的武器當然不能算新的,已經被用到什么樣了,就是什么樣的。

以下是不同時間會發生的不同事件:

在每個整點,即每個小時的第0分, 雙方的司令部中各有一個武士降生。

紅方司令部按照 iceman、lion、wolf、ninja、dragon 的順序制造武士。

藍方司令部按照 lion、dragon、ninja、iceman、wolf 的順序制造武士。

制造武士需要生命元。

制造一個初始生命值為 m 的武士,司令部中的生命元就要減少 m 個。

如果司令部中的生命元不足以制造某武士,那么司令部就等待,直到獲得足夠生命元后的第一個整點,才制造該武士。例如,在2:00,紅方司令部本該制造一個 wolf ,如果此時生命元不足,那么就會等待,直到生命元足夠后的下一個整點,才制造一個 wolf。

在每個小時的第5分,該逃跑的lion就在這一時刻逃跑了。

在每個小時的第10分:所有的武士朝敵人司令部方向前進一步。即從己方司令部走到相鄰城市,或從一個城市走到下一個城市。或從和敵軍司令部相鄰的城市到達敵軍司令部。

在每個小時的第20分:每個城市產出10個生命元。生命元留在城市,直到被武士取走。

在每個小時的第30分:如果某個城市中只有一個武士,那么該武士取走該城市中的所有生命元,並立即將這些生命元傳送到其所屬的司令部。

在每個小時的第35分,擁有arrow的武士放箭,對敵人造成傷害。放箭事件應算發生在箭發出的城市。注意,放箭不算是戰斗,因此放箭的武士不會得到任何好處。武士在沒有敵人的城市被箭射死也不影響其所在城市的旗幟更換情況。

在每個小時的第38分,擁有bomb的武士評估是否應該使用bomb。如果是,就用bomb和敵人同歸於盡。

在每個小時的第40分:在有兩個武士的城市,會發生戰斗。 如果敵人在5分鍾前已經被飛來的arrow射死,那么仍然視為發生了一場戰斗,而且存活者視為獲得了戰斗的勝利。此情況下不會有“武士主動攻擊”,“武士反擊”,“武士戰死”的事件發生,但戰斗勝利后應該發生的事情都會發生。如Wolf一樣能繳獲武器,旗幟也可能更換,等等。在此情況下,Dragon同樣會通過判斷是否應該輪到自己主動攻擊來決定是否歡呼。

在每個小時的第50分,司令部報告它擁有的生命元數量。

在每個小時的第55分,每個武士報告其擁有的武器情況。

武士到達對方司令部后就算完成任務了,從此就呆在那里無所事事。

任何一方的司令部里若是出現了2個敵人,則認為該司令部已被敵人占領。

任何一方的司令部被敵人占領,則戰爭結束。戰爭結束之后就不會發生任何事情了。

給定一個時間,要求你將從0點0分開始到此時間為止的所有事件按順序輸出。事件及其對應的輸出樣例如下:



1) 武士降生
輸出樣例: 000:00 blue lion 1 born

表示在 0點0分,編號為1的藍魔lion武士降生
如果造出的是dragon,那么還要多輸出一行,例:

000:00 blue dragon 1 born
Its morale is 23.34

表示該該dragon降生時士氣是23. 34(四舍五入到小數點后兩位)

如果造出的是lion,那么還要多輸出一行,例:
000:00 blue lion 1 born
Its loyalty is 24

表示該lion降生時的忠誠度是24

2) lion逃跑
輸出樣例: 000:05 blue lion 1 ran away
表示在 0點5分,編號為1的藍魔lion武士逃走

3) 武士前進到某一城市
輸出樣例: 000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在 0點10分,紅魔1號武士iceman前進到1號城市,此時他生命值為20,攻擊力為30
對於iceman,輸出的生命值和攻擊力應該是變化后的數值

4)武士放箭
輸出樣例: 000:35 blue dragon 1 shot
表示在 0點35分,編號為1的藍魔dragon武士射出一支箭。如果射出的箭殺死了敵人,則應如下輸出:
000:35 blue dragon 1 shot and killed red lion 4
表示在 0點35分,編號為1的藍魔dragon武士射出一支箭,殺死了編號為4的紅魔lion。

5)武士使用bomb
輸出樣例: 000:38 blue dragon 1 used a bomb and killed red lion 7
表示在 0點38分,編號為1的藍魔dragon武士用炸彈和編號為7的紅魔lion同歸於盡。

6) 武士主動進攻
輸出樣例:000:40 red iceman 1 attacked blue lion 1 in city 1 with 20 elements and force 30
表示在0點40分,1號城市中,紅魔1號武士iceman 進攻藍魔1號武士lion,在發起進攻前,紅魔1號武士iceman生命值為20,攻擊力為 30

7) 武士反擊
輸出樣例:001:40 blue dragon 2 fought back against red lion 2 in city 1
表示在1點40分,1號城市中,藍魔2號武士dragon反擊紅魔2號武士lion

8) 武士戰死
輸出樣例:001:40 red lion 2 was killed in city 1
被箭射死的武士就不會有這一條輸出。

9) 武士歡呼
輸出樣例:003:40 blue dragon 2 yelled in city 4

10) 武士獲取生命元( elements )
輸出樣例:001:40 blue dragon 2 earned 10 elements for his headquarter

輸出不包括在30分不是通過戰斗獲取的elements

11) 旗幟升起
輸出樣例:004:40 blue flag raised in city 4

12) 武士抵達敵軍司令部
輸出樣例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此時他生命值為20,攻擊力為30)對於iceman,輸出的生命值和攻擊力應該是變化后的數值

13) 司令部被占領
輸出樣例:003:10 blue headquarter was taken

14)司令部報告生命元數量
000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0點50分,紅方司令部有100個生命元,藍方有120個

15)武士報告武器情況
000:55 blue wolf 2 has arrow(2),bomb,sword(23)
000:55 blue wolf 4 has no weapon
000:55 blue wolf 5 has sword(20)
表示在0點55分,藍魔2號武士wolf有一支arrow(這支arrow還可以用2次),一個bomb,還有一支攻擊力為23的sword。
藍魔4號武士wolf沒武器。
藍魔5號武士wolf有一支攻擊力為20的sword。
交代武器情況時,次序依次是:arrow,bomb,sword。如果沒有某種武器,某種武器就不用提。報告時,先按從西向東的順序所有的紅武士報告,然后再從西向東所有的藍武士報告。

輸出事件時:

首先按時間順序輸出;

同一時間發生的事件,按發生地點從西向東依次輸出. 武士前進的事件, 算是發生在目的地。

在一次戰斗中有可能發生上面的 611 號事件。這些事件都算同時發生,其時間就是戰斗開始時間。一次戰斗中的這些事件,序號小的應該先輸出。

兩個武士同時抵達同一城市,則先輸出紅武士的前進事件,后輸出藍武士的。

顯然,13號事件發生之前的一瞬間一定發生了12號事件。輸出時,這兩件事算同一時間發生,但是應先輸出12號事件

雖然任何一方的司令部被占領之后,就不會有任何事情發生了。但和司令部被占領同時發生的事件,全都要輸出。

輸入
第一行是t,代表測試數據組數
每組樣例共三行。
第一行,五個整數 M,N,R,K, T。其含義為:

每個司令部一開始都有M個生命元( 1 <= M <= 10000)
兩個司令部之間一共有N個城市( 1 <= N <= 20 )
arrow的攻擊力是R
lion每經過一場未能殺死敵人的戰斗,忠誠度就降低K。
要求輸出從0時0分開始,到時間T為止(包括T) 的所有事件。T以分鍾為單位,0 <= T <= 5000

第二行:五個整數,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它們都大於0小於等於10000

第三行:五個整數,依次是 dragon 、ninja、iceman、lion、wolf 的攻擊力。它們都大於0小於等於10000

輸出
對每組數據,先輸出一行:
Case n:
如對第一組數據就輸出 Case1:
然后按恰當的順序和格式輸出到時間T為止發生的所有事件。每個事件都以事件發生的時間開頭,時間格式是“時: 分”,“時”有三位,“分”有兩位。

樣例輸入
1
20 1 10 10 1000
20 20 30 10 20
5 5 5 5 5
樣例輸出
Case 1:
000:00 blue lion 1 born
Its loyalty is 10
000:10 blue lion 1 marched to city 1 with 10 elements and force 5
000:30 blue lion 1 earned 10 elements for his headquarter
000:50 20 elements in red headquarter
000:50 20 elements in blue headquarter
000:55 blue lion 1 has no weapon
001:00 blue dragon 2 born
Its morale is 0.00
001:10 blue lion 1 reached red headquarter with 10 elements and force 5
001:10 blue dragon 2 marched to city 1 with 20 elements and force 5
001:30 blue dragon 2 earned 10 elements for his headquarter
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
001:55 blue lion 1 has no weapon
001:55 blue dragon 2 has arrow(3)
002:10 blue dragon 2 reached red headquarter with 20 elements and force 5
002:10 red headquarter was taken
View Code
#include<iostream>  
#include<string>  
#include<vector>  
#include<cstdio>  
using namespace std;  
enum Knight_name{dragon, ninja, iceman, lion, wolf};//武士名稱  
enum Weapon_name{sword, bomb, arrow};//武器名稱  
string Knight[5] = {"dragon", "ninja", "iceman", "lion", "wolf"};//武士名稱,輸出使用  
Knight_name Order[2][5] = {{iceman, lion, wolf, ninja, dragon},//制造順序  
                           {lion, dragon, ninja, iceman, wolf}};  
string Color[2] = {"red", "blue"};//司令部顏色,輸出使用  
string Weapons_[3] = {"sword", "bomb", "arrow"};//武器名稱,輸出使用  
int Attack_[5];//各武士初始攻擊力  
int Loyal_reduce;//lion未殺死敵人所減少士氣  
int Hour, Minute;//計時器  
int Total_Minutes;//終止時間  
int Life_Make[5];//制造各種武士所需生命元  
int arrow_attack;//arrow攻擊力  
void Print_time(){//輸出前面時間  
    cout.width(3); cout.fill('0');  
    cout << Hour << ':';cout.width(2);  
    cout << Minute << ' ';  
}  
class City;  
class Command;  
class Weapon{//武器  
private:  
    int name, sword_attack, arrow_usetime;//武器名稱,sword攻擊力,arrow剩余使用次數  
public:  
    Weapon(int i, int satt):name(i), sword_attack(satt),arrow_usetime(3){}//武器狀態初始化  
    bool sword_dull(){//sword變鈍  
        sword_attack = int (sword_attack * 0.8);  
        return sword_attack;  
    }  
    int &usetime(){return arrow_usetime;}  
    int sw_atk(){return sword_attack;}  
};  
class Warrior{//士兵  
private:  
    int Num, Life, Attack, Loyal, Step, l_life;//編號,生命力,攻擊力,忠誠度,步數  
    Knight_name name;//武士名稱  
    double Morale;//士氣  
    City* City_Belong_to;//所屬城市  
    Command* Command_Belong_to;//所屬司令部  
    bool If_win,If_kill;//戰斗是否獲勝,是否殺死敵人  
    Weapon* weapon[3];//裝備  
public:  
    Warrior(int n, Knight_name &name_, int &life, int &t_life,Command *COMD){//初始化士兵屬性  
        Num = n; name = name_; Life = life; Attack = Attack_[name]; Step = 0; l_life = 0;  
        weapon[0] = NULL; weapon[1] = NULL; weapon[2] = NULL;  
        switch(name){  
            case dragon:case iceman: weapon[Num % 3] = new Weapon(Num % 3, int(Attack_[name] * 0.2)); break;  
            case ninja: weapon[Num % 3] = new Weapon(Num % 3, int(Attack_[name] * 0.2));  
                        weapon[(Num + 1) % 3] = new Weapon((Num + 1) % 3, int(Attack_[name] * 0.2)); break;  
            default: break;  
        };  
        if (weapon[sword]) if (!weapon[sword]->sw_atk()) weapon[sword] = NULL;//若初始武器攻擊為0,則delete  
        Morale = double(t_life) / double(Life);  
        Loyal = t_life; If_win = false; If_kill = false;  
        City_Belong_to = NULL; Command_Belong_to = COMD;  
        cout << Knight[name] << ' ' << Num << " born\n";  
        if (name == dragon){  
            cout << "Its morale is ";  
            cout.precision(2);  
            cout << fixed << Morale << endl;  
        }  
        if (name == lion){cout << "Its loyalty is " << Loyal << endl;}  
    }  
    bool &IF_win(){return If_win;}  
    int life(){return Life;}  
    bool Minute_5();//lion是否逃跑 輸出  
    void Minute_10(bool );//武士前進輸出  
    void Minute_30(int );//獲取城市生命元及輸出  
    void arrow_shot();//使用弓箭輸出  
    void Be_shoted();//被射中處理及輸出  
    void Change_City(City * Cp){City_Belong_to = Cp;}  
    void Morale_Change(){If_win ? Morale += 0.2: Morale -=0.2;}  
    bool weapon_(Weapon_name name){return weapon[name];}  
    void Use_bomb(Warrior *);//使用bomb輸出  
    int fight(Warrior* Wp){//假設戰斗,判斷是否會獲勝  
        if (Life > 0 and Wp->Life > 0){  
            int swatk = 0;  
            if (weapon[sword]) swatk = weapon[sword]->sw_atk();  
            if (Wp->Life - Attack- swatk > 0){  
                if (Wp->name == ninja) return 0;  
                else{  
                    int E_swatk = 0;  
                    if (Wp->weapon[sword]) E_swatk = (Wp->weapon[sword])->sw_atk();  
                    if (Life - (Wp->Attack / 2) - E_swatk > 0) return 0;  
                    else return -1;  
                }  
            }else return 1;  
        }  
        return 0;  
    }  
    bool bomb(Warrior *, int);//判斷是否使用bomb  
    void Fight(Warrior *);//武士戰斗處理及輸出  
    void Dead();//武士死亡輸出  
    void account(Warrior * Wp){//部分戰后處理  
        If_win = true;  
        if(If_kill) {Wp->Dead();If_kill = false;}  
        if (Wp->name == lion) Life += Wp->l_life;  
        if (name == wolf)  
            for (int i = 0; i < 3; ++i)  
                if (Wp->weapon[i] and !weapon[i]){  
                    weapon[i] = Wp->weapon[i];  
                    Wp->weapon[i] = NULL;  
                }  
        Morale_Change();  
    }  
    void Reward();//戰勝后獲取獎勵  
    void ADD(int);//所屬司令部增加生命元  
    void Loyal_Reduce(){Loyal -= Loyal_reduce;}  
    void Report_weapon();//報告武器使用情況  
    ~Warrior(){  
        for (int i = 0; i < 3; ++i)  
            if (weapon[i]) delete weapon[i];  
    }  
};  
class City{  
private:  
    int Number, Life, Flag, Flag_G[2];//城市編號,生命元,旗幟,各方士兵連續勝利場次  
    Warrior *Warrior_In_City[2];  
public:  
    int Num(){return Number;}  
    int Life_(){return Life;}  
    City(int N){  
        Number = N; Life = 0; Flag = -1;//-1 表示無旗城市  
        Warrior_In_City[0] = NULL; Flag_G[0] = 0;  
        Warrior_In_City[1] = NULL; Flag_G[1] = 0;  
    }  
    void Minute_5(){//處理逃跑lion  
        for(int i = 0; i < 2; ++i)  
            if(Warrior_In_City[i]) if (Warrior_In_City[i]->Minute_5()){  
                delete Warrior_In_City[i]; Warrior_In_City[i] = NULL;  
            }  
    }  
    void Move(City* Cp, int i){//warrior前進  
        Warrior_In_City[i] = Cp->Warrior_In_City[i];  
        if(Warrior_In_City[i]) Warrior_In_City[i]->Change_City(this);  
    }  
    void Move(Command *, int);//warrior進入敵方司令部  
    void Move(Warrior *Wp, int i){//warrior從command進入city  
        Warrior_In_City[i] = Wp;  
        if (Warrior_In_City[i]) Warrior_In_City[i]->Change_City(this);  
    }  
    bool If_exist(int i){return Warrior_In_City[i];}  
    void Minute_10(){//warrior前進輸出  
        if (Warrior_In_City[0]) Warrior_In_City[0]->Minute_10(false);  
        if (Warrior_In_City[1]) Warrior_In_City[1]->Minute_10(false);  
    }  
    void Add_Life(){Life += 10;}  
    void Minute_30(){//城內單獨warrior獲取生命元  
        for (int i = 0; i < 2; ++i)  
        if ((Warrior_In_City[i]) and (!Warrior_In_City[1-i])){  
            Warrior_In_City[i]->Minute_30(Life);  
            Life = 0; break;  
        }  
    }  
    void Minute_35(City* Cp[]){//處理arrow事件  
        for (int j = 0; j < 2; ++j)  
            if (Warrior_In_City[j]) if (Warrior_In_City[j]->weapon_(arrow))  
                if (Cp[1-j]) if ((Cp[1-j]->Warrior_In_City[1-j])){  
                    Warrior_In_City[j]->arrow_shot();  
                    Cp[1-j]->Warrior_In_City[1-j]->Be_shoted();  
                }  
    }  
    void Minute_38(){//處理bomb事件,順帶處理35分鍾時城市中兩只warrior均被被射死的情況  
        if (Warrior_In_City[0] and Warrior_In_City[1]){  
            bool p =false;  
            for (int i = 0; i < 2; ++i)  
                if (Warrior_In_City[i]->weapon_(bomb)){  
                    if (Flag == -1) p = Warrior_In_City[i]->bomb(Warrior_In_City[1-i], Number);  
                    else p = Warrior_In_City[i]->bomb(Warrior_In_City[1-i], Flag+1);  
                    if (p){  
                        delete Warrior_In_City[0]; Warrior_In_City[0] = NULL;  
                        delete Warrior_In_City[1]; Warrior_In_City[1] = NULL;  
                        break;  
                    }  
                }  
            if (!p and Warrior_In_City[0]->life() <= 0 and Warrior_In_City[1]->life() <= 0){  
                delete Warrior_In_City[0]; Warrior_In_City[0] = NULL;  
                delete Warrior_In_City[1]; Warrior_In_City[1] = NULL;  
            }  
        }  
    }  
    void Battle(){//戰斗及輸出,不進行生命元獎勵、獲取處理  
        if (Warrior_In_City[0] and Warrior_In_City[1]){  
            if (Flag == -1){  
                if (Number % 2) Warrior_In_City[0]->Fight(Warrior_In_City[1]);  
                else Warrior_In_City[1]->Fight(Warrior_In_City[0]);  
            }else  
                Warrior_In_City[Flag]->Fight(Warrior_In_City[1-Flag]);  
        }  
    }  
    void Flag_Set(int i){//戰斗后旗幟設置  
        if (i == -1){Flag_G[0] = 0; Flag_G[1] = 0;}  
        else{  
            ++Flag_G[i]; Flag_G[1-i] = 0;  
            if (Flag_G[i] == 2 and Flag != i){  
                Flag = i;  
                Print_time();  
                cout << Color[i] << " flag raised in city " << Number << endl;}  
        }  
    }  
    void Reward(int i){if(Warrior_In_City[i]) Warrior_In_City[i]->Reward();}  
    void Warrior_report(int i){if(Warrior_In_City[i]) Warrior_In_City[i]->Report_weapon();}  
    void Win_get(){//獎勵獲勝士兵生命元  
        for (int i = 0; i < 2; ++i)  
            if (Warrior_In_City[i]){  
                if (Warrior_In_City[i]->IF_win()){  
                    Warrior_In_City[i]->ADD(Life);  
                    Life = 0; Warrior_In_City[i]->IF_win() = false;  
                }else if (Warrior_In_City[i]->life() <=0){  
                    delete Warrior_In_City[i];  
                    Warrior_In_City[i] = NULL;  
                }  
            }  
    }  
};  
class Command{  
private:  
    int Total_Life, Knights_Num, Colour, Enemy_Enter;//生命元,造士兵數量,command顏色,有多少敵人進入  
    bool Weather_Enter;//是否有敵人進入  
    Warrior* Enemys[2];//進入的敵人  
    Warrior* Knight;//warrior  
public:  
    int colour(){return Colour;}  
    string colour(bool p){return p? Color[Colour]: Color[1-Colour];}  
    Command(int TLife, int col){  
        Total_Life = TLife;Colour = col;  
        Knights_Num = 0;  
        Knight = NULL; Enemy_Enter = 0;  
        Weather_Enter = false;  
        Enemys[0] = NULL; Enemys[1] = NULL;  
    }  
    void Minute_0(){//制造warrior及輸出  
        if (Total_Life >= Life_Make[Order[Colour][Knights_Num % 5]]){  
            Total_Life -= Life_Make[Order[Colour][Knights_Num % 5]];  
            Print_time();  
            cout << Color[Colour] << ' ';  
            Knight = new Warrior(Knights_Num+1, Order[Colour][Knights_Num % 5], Life_Make[Order[Colour][Knights_Num% 5]], Total_Life, this);  
            Knights_Num++;  
        }  
    }  
    void Minute_5(){//處理逃跑lion  
        if (Knight) if (Knight->Minute_5()){delete Knight; Knight = NULL;}  
    }  
    void Move(City* Cp, int i){Cp->Move(Knight, i); Knight = NULL;}//warrior走出command  
    void Enemy_Move_In(Warrior* enemy){//敵方warrior進入  
        Enemys[Enemy_Enter] = enemy;  
        Weather_Enter = true;  
        ++Enemy_Enter;  
    }  
    void Minute_10(){//敵方warrior進入輸出  
        if (Weather_Enter){  
            Enemys[Enemy_Enter-1]->Minute_10(true);  
            Weather_Enter = false;  
        }  
    }  
    bool If_occupied(){//command是否被占領  
        if (Enemy_Enter == 2){  
            Print_time();  
            cout << Color[Colour] << " headquarter was taken\n";  
            return true;  
        }  
        return false;  
    }  
    void Minute_30(int Add_life){Total_Life += Add_life;}  
    int &Life(){return Total_Life;}  
    void Report_life(){//command報告生命元  
        Print_time();  
        cout << Total_Life << " elements in " << Color[Colour] << " headquarter\n";  
    }  
    void Report(){if (Enemy_Enter) Enemys[Enemy_Enter-1]->Report_weapon();}//已進入command的warrior仍要report  
    ~Command(){  
        if (Knight) delete Knight;  
        if (Enemys[0]) delete Enemys[0];  
        if (Enemys[1]) delete Enemys[1];  
    }  
};  
void Game_Start(){  
    int times = 0;  
    cin >> times;  
    for (int t = 0; t < times; ++t){  
        int M, N;//初始command生命元,城市數量  
        cin >> M >> N >> arrow_attack >> Loyal_reduce >> Total_Minutes;  
        Command COM[2] = {Command(M,0),Command(M,1)};  
        vector<City> Citys;  
        for (int i = 0; i < N; ++i){  
            City temp(i + 1);  
            Citys.push_back(temp);  
        }  
        for (int i = 0; i < 5; ++i)  
            cin >> Life_Make[i];  
        for (int i = 0; i < 5; ++i)  
            cin >> Attack_[i];  
        cout << "Case " << t + 1 << ":\n";  
        Hour = 0; Minute = 0;//計時開始  
        while(Hour * 60 <= Total_Minutes){  
            COM[0].Minute_0(); COM[1].Minute_0(); Minute = 5;//第0分鍾  
            if (Hour * 60 + Minute > Total_Minutes) break;//第5分鍾  
            else {  
                COM[0].Minute_5();  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)  
                    (*i).Minute_5();  
                COM[1].Minute_5();  
                Minute = 10;  
            }  
            if (Hour * 60 + Minute > Total_Minutes) break;//第10分鍾  
            else {  
                if (Citys[0].If_exist(1)) Citys[0].Move(&COM[0], 1);//warrior前進  
                for (int i = 0; i < N - 1; ++i)  
                    Citys[i].Move(&Citys[i+1], 1);  
                COM[1].Move(&Citys[N - 1], 1);  
                if (Citys[N-1].If_exist(0)) Citys[N-1].Move(&COM[1], 0);  
                for (int i = N - 1; i > 0; --i)  
                    Citys[i].Move(&Citys[i-1], 0);  
                COM[0].Move(&Citys[0], 0);  
                COM[0].Minute_10();//warrior移動輸出  
                bool p = COM[0].If_occupied();  
                for (int i = 0; i < N; ++i) Citys[i].Minute_10();  
                COM[1].Minute_10();  
                if (p + COM[1].If_occupied()) break;  
            }  
            Minute = 20;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第20分鍾  
            else  
                for (int i = 0; i < N; ++i) Citys[i].Add_Life();  
            Minute = 30;  
  
            if (Hour * 60 + Minute > Total_Minutes) break;//第30分鍾  
            else  
                for (int i = 0; i < N; ++i) Citys[i].Minute_30();  
            Minute = 35;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第35分鍾  
            else  
                if (N > 1){//city數大於1時才會發生arrow事件  
                    City* Cp[2] = {};  
                    Cp[0] = NULL; Cp[1] = &Citys[1];  
                    Citys[0].Minute_35(Cp);  
                    for (int i = 1; i < N-1; ++i){  
                        Cp[0] = &Citys[i-1]; Cp[1] = &Citys[i+1];  
                        Citys[i].Minute_35(Cp);  
                    }  
                    Cp[0] = &Citys[N-2]; Cp[1] = NULL;  
                    Citys[N-1].Minute_35(Cp);  
                }  
            Minute = 38;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第38分鍾  
            else  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)  
                    (*i).Minute_38();  
            Minute = 40;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第40分鍾  
            else{  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)//戰斗及輸出  
                    (*i).Battle();  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)//獎勵生命元  
                    (*i).Reward(0);  
                for (vector<City>::reverse_iterator i = Citys.rbegin(); i != Citys.rend(); ++i)  
                    (*i).Reward(1);  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)//獲取city生命元  
                    (*i).Win_get();  
            }  
            Minute = 50;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第50分鍾  
            else  
                COM[0].Report_life();COM[1].Report_life();  
            Minute = 55;  
            if (Hour * 60 + Minute > Total_Minutes) break;//第55分鍾  
            else{  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)  
                    (*i).Warrior_report(0);  
                COM[1].Report();COM[0].Report();  
                for (vector<City>::iterator i = Citys.begin(); i != Citys.end(); ++i)  
                    (*i).Warrior_report(1);  
            }  
            Minute = 0;  
            Hour++;  
        }  
    }  
}  
int main(){  
//  freopen("d:\\anser.txt", "w", stdout);  
    Game_Start();  
//  fclose(stdout);  
    return 0;  
}  
bool Warrior::Minute_5(){  
    if (name == lion) if (Loyal <= 0){  
        Print_time();  
        cout << Command_Belong_to->colour(true) << " lion " << Num << " ran away\n";  
        return true;  
    }  
    return false;  
}  
void Warrior::Minute_10(bool If_arrive){  
    ++Step;  
    if (name == iceman and !(Step % 2)){  
        if (Life < 10) Life = 1;  
        else Life -= 9;  
        Attack += 20;  
    }  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num;  
    if (If_arrive)  
        cout << " reached " << Command_Belong_to->colour(false) << " headquarter";  
    else cout << " marched to city " << City_Belong_to->Num();  
    cout << " with " << Life << " elements and force " << Attack << endl;  
}  
void Warrior::Minute_30(int Add_life){  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " earned " << Add_life << " elements for his headquarter\n";  
    Command_Belong_to->Minute_30(Add_life);  
}  
void Warrior::arrow_shot(){  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " shot";  
    weapon[arrow]->usetime()--;  
    if(!weapon[arrow]->usetime()){delete weapon[arrow]; weapon[arrow] = NULL;}  
}  
void Warrior::Be_shoted(){  
    Life -= arrow_attack;  
    if (Life <= 0){cout << " and killed " << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num;}  
    cout << endl;  
}  
void City::Move(Command *Cp, int i){  
    Cp->Enemy_Move_In(Warrior_In_City[i]);  
    Warrior_In_City[i] = NULL;  
}  
void Warrior::Use_bomb(Warrior *Wp){  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " used a bomb and killed " << (Wp->Command_Belong_to)->colour(true) << ' ' << Knight[Wp->name] << ' ' << Wp->Num << endl;  
}  
bool Warrior::bomb(Warrior *Wp, int p){  
    if ((p + Command_Belong_to->colour()) % 2){  
        if (fight(Wp) == -1) {Use_bomb(Wp); return true;}  
    }else  
        if (Wp->fight(this) == 1) {Use_bomb(Wp); return true;}  
    return false;  
}  
void Warrior::Dead(){  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " was killed in city " << City_Belong_to->Num() << endl;  
}  
void Warrior::Fight(Warrior *Wp){  
    Warrior *Wp_win = NULL; Warrior *Wp_lose = NULL;  
    l_life = Life; Wp->l_life = Wp->Life;  
    if (Life > 0 and (Wp->Life) > 0){  
        int swatk = 0;  
        if (weapon[sword]) swatk = weapon[sword]->sw_atk();  
        Print_time();  
        cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " attacked " << (Wp->Command_Belong_to)->colour(true) << ' ' << Knight[Wp->name] << ' ' << Wp->Num << " in city " << City_Belong_to->Num() << " with " << Life << " elements and force " << Attack << endl;  
        Wp->Life = Wp->Life - Attack - swatk;  
        if (swatk) if (!weapon[sword]->sword_dull()){delete weapon[sword]; weapon[sword] = NULL;}  
        if (Wp->Life > 0){  
            if (Wp->name == ninja) {City_Belong_to->Flag_Set(-1);Morale_Change();Loyal_Reduce();}  
            else{  
                int E_swatk = 0;  
                if (Wp->weapon[sword]) E_swatk = (Wp->weapon[sword])->sw_atk();  
                Print_time();  
                cout << (Wp->Command_Belong_to)->colour(true) << ' ' << Knight[Wp->name] << ' ' << Wp->Num << " fought back against " << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " in city " << City_Belong_to->Num() <<endl;  
                Life = Life - (Wp->Attack / 2) - E_swatk;  
                if (E_swatk) if(!(Wp->weapon[sword])->sword_dull()){delete Wp->weapon[sword]; Wp->weapon[sword] = NULL;}  
                if (Life > 0) {City_Belong_to->Flag_Set(-1);Morale_Change();Wp->Morale_Change();Loyal_Reduce();Wp->Loyal_Reduce();}  
                else{Wp->If_kill = true;Wp_lose = this;Wp_win = Wp;}  
            }  
        }else{If_kill = true;Wp_win = this;Wp_lose = Wp;}  
    }else{  
        if (Life > 0){Wp->l_life = 0;Wp_win = this;Wp_lose = Wp;}  
        else {l_life = 0;Wp_lose = this;Wp_win = Wp;}  
    }  
    if (Wp_win){Wp_win->account(Wp_lose);}  
    if (name == dragon and Life > 0 and Morale > 0.8){  
        Print_time();  
        cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " yelled in city " << City_Belong_to->Num() << endl;  
    }  
    if (Wp_win){  
        Print_time();  
        cout << (Wp_win->Command_Belong_to)->colour(true) << ' ' << Knight[Wp_win->name] << ' ' << Wp_win->Num << " earned " << City_Belong_to->Life_() << " elements for his headquarter\n";  
        (Wp_win->City_Belong_to)->Flag_Set((Wp_win->Command_Belong_to)->colour());  
    }  
}  
void Warrior::Reward(){  
    if (If_win)  
        if (Command_Belong_to->Life() > 7){  
            Command_Belong_to->Life() -= 8;  
            Life += 8;  
        }  
}  
void Warrior::ADD(int life){Command_Belong_to->Life() += life;}  
void Warrior::Report_weapon(){  
    bool p = false;  
    Print_time();  
    cout << Command_Belong_to->colour(true) << ' ' << Knight[name] << ' ' << Num << " has ";  
    for (int i = 2; i >= 0; --i)  
        if (weapon[i]){  
            if (p) cout << ',';else p = true;  
            cout << Weapons_[i];  
            if (i == 2) cout << '(' << weapon[arrow]->usetime() << ')';  
            if (i == 0) cout << '(' << weapon[sword]->sw_atk() << ')';  
        }  
    if(!p) cout << "no weapon";  
    cout << endl;  
}  
View Code
#include <map>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
using namespace std;
class SAM* C[25][2];
int M, N, R, K, T;
int chp[25], flag[25], lastwin[25], win[25];
bool arr[25];
map<string, int> HP, ATK;
int offen(int x){
    if(flag[x] != -1)return flag[x];
    return !(x & 1);
}
string int2str(int x){
    string str = "";
    while(x)
        str = char(x % 10 + '0') + str, x /= 10;
    return str;
}
class Weapon{
public:
    int atk;
    Weapon(int type, int _atk){
        if(type == 0)atk = _atk / 5;
        if(type == 1)atk = 100;
        if(type == 2)atk = 3;
    }
};
class SAM{
public:
    int atk;
    int hp;
    int id;
    int loyalty;
    int step;
    string color;
    string type;
    double morale;
    Weapon* wea[3];
    SAM(string _color, int _id, string _type, double hhp):color(_color), type(_type), id(_id){
        step = morale = 0; loyalty = 100;
        hp = HP[type];
        atk = ATK[type];         
        memset(wea, 0 ,sizeof(wea));
        auto WA = new Weapon(id % 3, atk), WB = new Weapon((id + 1) % 3, atk);
        if(WA->atk == 0)WA = NULL;
        if(WB->atk == 0)WB = NULL;
        if(type == "dragon"){
            wea[id % 3] = WA;
            morale = (double)hhp / HP["dragon"];
        }
        if(type == "ninja")wea[id % 3] = WA, wea[(id + 1) % 3] = WB;
        if(type == "iceman")wea[id % 3] = WA;
        if(type == "lion")loyalty = hhp;
    }
    operator string(){
        return color + ' ' + type + ' ' + int2str(id);
    }
    string attr(){
        return "with " + int2str(hp) + " elements and force " + int2str(atk);
    }
    int getatk(bool);
    int usesword(bool);
};
string Sam_type[2][5] = {
    {"iceman", "lion", "wolf", "ninja", "dragon"},
    {"lion", "dragon", "ninja", "iceman", "wolf"},
};
class HEA{
public:
    int hp;
    int Stot;
    int type;
    int pos;
    int rew;
    string color;
    HEA(){}
    HEA(string _color, int _hp):color(_color), hp(_hp){
        if(color == "red")type = 0, pos = 0;
        else type = 1, pos = N + 1;
        Stot = 0;
    }
    void summon();
}H[2];
class Game{
public:
    int t;
    void reset(int cas);
    void turn();
    void escape();
    void move();
    void gethp();
    void shoot();
    void usebomb();
    void war();
    void print15(SAM);
}game;
void Game::reset(int cas){
    printf("Case %d:\n", cas);
    t = 0;
    for(int i = 0; i <= N + 1; i++){
        C[i][0] = C[i][1] = NULL;
        flag[i] = lastwin[i] = -1;
        chp[i] = 0;
    }
}
void Game::escape(){
    for(int i = 0; i <= N + 1; i++)
        for(int j = 0; j < 2; j++)
            if(C[i][j] && C[i][j]->loyalty <= 0 && i != H[j ^ 1].pos){
                printf("%03d:05 %s ran away\n", game.t / 60, string(*C[i][j]).c_str()), 
                C[i][j] = NULL;
            }
}
void Game::move(){
    bool end = 0;
    int d[2] = {-1, 1};
    SAM *tmp[25][2] = {NULL};
    for(int i = 0; i <= N + 1; i++)           
        for(int j = 0; j < 2; j++){
            int u = i + d[j];
            if(i ==  H[j ^ 1].pos)tmp[i][j] = C[i][j];
            if(C[u][j]){
                if(u < 0 || u > N + 1)continue;
                SAM *S = C[u][j];
                if(!(++S->step & 1) && S->type == "iceman")S->atk += 20, S->hp = max(1, S->hp - 9);
                tmp[i][j] = S;
                if(i == H[j ^ 1].pos){
                    printf("%03d:10 %s reached %s headquarter %s\n", game.t / 60, string(*S).c_str(), H[j ^ 1].color.c_str(), S->attr().c_str());
                    if(C[i][j]){
                        printf("%03d:10 %s headquarter was taken\n", game.t / 60, H[j ^ 1].color.c_str());
                        end = 1;
                    }
                }
                else printf("%03d:10 %s marched to city %d %s\n", game.t / 60, string(*S).c_str(), i, S->attr().c_str());
            }
        }
    for(int i = 0; i <= N + 1; i++)
        for(int j = 0; j < 2; j++)
            C[i][j] = tmp[i][j];
    if(end)game.t = -1;
}
void Game::gethp(){
    for(int i = 1; i <= N ; i++)
        for(int j = 0; j < 2; j++)
            if(C[i][j] && !C[i][j ^ 1]){
                H[j].hp += chp[i];
                printf("%03d:30 %s earned %d elements for his headquarter\n", game.t / 60, string(*C[i][j]).c_str(), chp[i]);
                chp[i] = 0;
            }
}
void Game::shoot(){
    memset(arr, 0, sizeof(arr));
    for(int i = 0; i <= N + 1; i++)
        for(int j = 0; j < 2; j++){
            SAM *u = C[i][j], *v = NULL;
            int p;
            if(j == 0)p = i + 1;
            else p = i - 1;
            if(p >= 0 && p <= N + 1)v = C[p][j ^ 1];
            if(!u || !v || !u->wea[2])continue;
            v->hp -= R;
            u->wea[2]->atk--;
            if(!u->wea[2]->atk)u->wea[2] = NULL;
            if(v->hp > 0)printf("%03d:35 %s shot\n", game.t / 60, string(*u).c_str());
            else{
                printf("%03d:35 %s shot and killed %s\n", game.t / 60, string(*u).c_str(), string(*v).c_str());
                arr[p] = 1;
            }
        }
}
void Game::usebomb(){
    for(int i = 1; i <= N; i++){
        int p = offen(i);
        auto &u = C[i][p], &v = C[i][p ^ 1];
        if(!u || !v || arr[i])continue;
        if(v->wea[1] && u->getatk(0) >= v->hp){
            printf("%03d:38 %s used a bomb and killed %s\n", game.t / 60, string(*v).c_str(), string(*u).c_str());
            u = v = NULL;
        }
        else if(u->wea[1] && u->getatk(0) < v->hp && v->getatk(1) >= u->hp && v->type != "ninja"){
            printf("%03d:38 %s used a bomb and killed %s\n", game.t / 60, string(*u).c_str(), string(*v).c_str());
            u = v = NULL;
        }
    }
}
void fight(int pos, int p, bool defense){
    auto &u = C[pos][p], &v = C[pos][p ^ 1];
    int tmp = max(0, v->hp);
    if(u->hp > 0 && v->hp > 0)
        if(!defense || u->type != "ninja"){
            v->hp -= u->getatk(defense);
            u->usesword(1);
            if(defense)
                printf("%03d:40 %s fought back against %s in city %d\n", game.t / 60, string(*u).c_str(), string(*v).c_str(), pos);
            else printf("%03d:40 %s attacked %s in city %d %s\n", game.t / 60, string(*u).c_str(), string(*v).c_str(), pos, u->attr().c_str());
        }
    if(v->hp <= 0 && u->hp > 0){
        if(!arr[pos])
            printf("%03d:40 %s was killed in city %d\n", game.t / 60, string(*v).c_str(), pos);
        win[pos] = p;
        if(v->type == "lion")u->hp += tmp;
        if(u->type == "wolf")
            for(int i = 0; i < 3; i++)
                if(!u->wea[i])u->wea[i] = v->wea[i];
    }
}
void Game::war(){
    memset(win, -1, sizeof(win));
    H[0].rew = H[0].hp / 8;
    H[1].rew = H[1].hp / 8;
    for(int i = 1; i <= N; i++)
        if(C[i][0] && C[i][1]){
            int p = offen(i);
            fight(i, p, 0);
            fight(i, p ^ 1, 1);
            if(C[i][p]->morale > 0.8 && C[i][p]->hp > 0)
                printf("%03d:40 %s yelled in city %d\n", game.t / 60, string(*C[i][p]).c_str(), i);
            if(win[i] != -1){
                int w = win[i];
                printf("%03d:40 %s earned %d elements for his headquarter\n", game.t / 60, string(*C[i][w]).c_str(), chp[i]);
                H[w].hp += chp[i]; chp[i] = 0;
                if(lastwin[i] == w && flag[i] != w){
                    flag[i] = w;
                    printf("%03d:40 %s flag raised in city %d\n", game.t / 60, H[w].color.c_str(), i);
                }
                lastwin[i] = w; 
            }
            for(int j = 0; j < 2; j++)
                if(C[i][j]->type == "dragon"){
                    if(j == win[i])C[i][j]->morale += 0.2;
                    else C[i][j]->morale -= 0.2;
                }
            if(C[i][0]->hp > 0 && C[i][1]->hp > 0){
                for(int j = 0; j < 2; j++)
                    if(C[i][j]->type == "lion")C[i][j]->loyalty -= K;
                lastwin[i] = -1;
            }
        }
    for(int i = 1; i <= N; i++)
        for(int j = 0; j < 2; j++)
            if(C[i][j] && C[i][j]->hp <= 0)C[i][j] = NULL;
    for(int i = N; i && H[0].rew; i--)
        if(win[i] == 0){
            H[0].hp -= 8; H[0].rew--;
            C[i][0]->hp += 8;
        }
    for(int i = 1; i <= N && H[1].rew; i++)
        if(win[i] == 1){
            H[1].hp -= 8; H[1].rew--;
            C[i][1]->hp += 8;
        }
}
void Game::turn(){
    int M = t % 60;
    if(M == 0)H[0].summon(), H[1].summon();
    if(M == 5)escape();
    if(M == 10)move();
    if(t == -1)return;
    if(M == 20)for(int i = 1; i <= N; i++)chp[i] += 10;
    if(M == 30)gethp();
    if(M == 35)shoot();
    if(M == 38)usebomb();
    if(M == 40)war();
    if(M == 50)
        for(int i = 0; i < 2; i++)
            printf("%03d:50 %d elements in %s headquarter\n", game.t / 60, H[i].hp, H[i].color.c_str());
    if(M == 55){
        for(int i = 0; i <= N + 1; i++)
            if(C[i][0])print15(*C[i][0]);
        for(int i = 0; i <= N + 1; i++)
            if(C[i][1])print15(*C[i][1]);                 
    }
    t++;
}
void Game::print15(SAM S){
    printf("%03d:55 %s has ", game.t / 60, string(S).c_str());
    if(S.wea[2]){
        printf("arrow(%d)", S.wea[2]->atk);
        if(S.wea[1] || S.wea[0])putchar(',');
        else putchar('\n');
    }
    if(S.wea[1]){
        printf("bomb");
        if(S.wea[0])putchar(',');
        else putchar('\n');
    }
    if(S.wea[0])printf("sword(%d)\n", S.wea[0]->atk);
    if(!S.wea[0] && !S.wea[1] && !S.wea[2])puts("no weapon");
}
int SAM::usesword(bool con){
    auto &x = wea[0];
    if(!x)return 0;
    int res = x->atk;
    if(con){
        x->atk = (int)(x->atk * 0.8);
        if(!x->atk)x = NULL;
    }
    return res;
}
int SAM::getatk(bool defense){
    if(defense)return atk / 2 + usesword(0);
    else return atk + usesword(0);
}
void HEA::summon(){
    string Stype = Sam_type[type][Stot % 5];
    if(HP[Stype] <= hp){
        hp -= HP[Stype];
        Stot++;
        SAM* S = new SAM(color, Stot, Stype, hp);
        C[pos][type] = S;
        printf("%03d:00 %s born\n", game.t / 60, string(*S).c_str());
        if(S->type == "dragon")
            printf("Its morale is %.2lf\n", S->morale);
        if(S->type == "lion")
            printf("Its loyalty is %d\n", S->loyalty);
    }
}
int main(){
    int tot;
    cin >> tot;
    for(int cas = 1; cas <= tot; cas++){
        cin >> M >> N >> R >> K >> T;
        game.reset(cas);
        H[0] = HEA("red", M);
        H[1] = HEA("blue", M);
        cin >> HP["dragon"] >> HP["ninja"] >> HP["iceman"] >> HP["lion"] >> HP["wolf"];
        cin >> ATK["dragon"] >> ATK["ninja"] >> ATK["iceman"] >> ATK["lion"] >> ATK["wolf"];
        while(game.t <= T && game.t != -1)
            game.turn();
    }
    return 0;
}
View Code
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
const double EPS = 1e-10;
using namespace std;
enum EEventType { EVENT_BORN, EVENT_LION_RUN,EVENT_MARCH, EVENT_ARROW,EVENT_BOMB,EVENT_ATTACK,
                  EVENT_FIGHTBACK,EVENT_KILLED, EVENT_YELL, EVENT_EARNMONEY,
                  EVENT_FLAG, EVENT_REACH,EVENT_CITYTAKEN,EVENT_PRINTMONEY,EVENT_WARRIOR_REPORT };
enum { WEAPON_SWORD,WEAPON_BOMB,WEAPON_ARROW };
enum { DRAGON,NINJA,ICEMAN,LION,WOLF};
#define WEAPON_NUM 3
#define WARRIOR_NUM 5
class CWeapon
{
    public:
        int nKindNo;
        int nForce;
        static const char * Names[WEAPON_NUM];
        static int nArrowForce;
        bool operator<( const CWeapon & w)  const
        {
            return w.nKindNo < nKindNo;
        }
};


#define COLOR_RED 0
#define COLOR_BLUE 1
#define COLOR_NONE 3

class CHeadquarter;
class CKingdom;
class CWarrior;
class CCity;
class CWeapon;
typedef  CWarrior* PWARRIOR;
string MyIntToStr( int n)
{
    char szTmp[300];
    sprintf(szTmp,"%d",n);
    return szTmp;
}
//cls CWarrior
class CWarrior
{
    friend class CHeadquarter;
    friend bool MyCompare(const PWARRIOR & p1, const PWARRIOR & p2);
protected:
    int nStrength;
    int nForce;
    int nCityNo;
    int nId;
    bool bShotToDeath;
    CHeadquarter * pHeadquarter;
public:
    static int InitalForce [WARRIOR_NUM];
    static const char * Names[WARRIOR_NUM];
    static int InitialLifeValue [WARRIOR_NUM];
    virtual bool Runaway() { return false; }
    virtual bool HasBomb() { return false; }
    virtual int GetSwordForce() { return 0;}
    virtual int UseSword() { return 0;}

    virtual void AddMorale(double a) { };
    virtual void EarnWeapons( CWarrior * pEnemy) { }

    virtual string ReportWeapons() { return "";}

//    virtual void PrintResult(int nTime,int nKindNo);
//    virtual void PrintResult(int nTime) = 0;
    bool virtual VirtualAttack( CWarrior * pEnemy);
    bool virtual VirtualFightback( CWarrior * pEnemy);
    virtual ~CWarrior() { }
    virtual int Attack( CWarrior * pEnemy);
    virtual int  HurtedBy(CWarrior * pEnemy);
    virtual string GetName() = 0;
    virtual void Killed();
    virtual void March();

    int AttackedByArrow( int nArrowForce) {
        nStrength -= nArrowForce;
        if( nStrength <= 0 ) {
            nStrength = 0;
            bShotToDeath = true;
        }
        return nStrength;
    }
    virtual int ShootArrow() { return 0; } //返回箭的攻擊力
    string GetColorStr();
    int GetColor() const;
    CWarrior(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
        nId(nId_),nStrength(nStrength_),nForce(nForce_),nCityNo(nCityNo_),pHeadquarter(pHeadquarter_),
            bShotToDeath(false)
    {
    }
    int GetStrength( )
    {
        return nStrength;
    }
    int GetForce()
    {
        return nForce;
    }
    void SetStrength(int n)
    {
        nStrength = n;
    }
    void SetForce(int n)
    {
        nForce = n;
    }
    int GetPosition() 
    {
        return nCityNo;
    }
    virtual void FightBack(CWarrior * pEnemy) {
        int nSwordForce = UseSword();
        pEnemy->nStrength -= nForce/2 + nSwordForce;
    }
};
class CWeaponWarrior:public CWarrior
{
public:
    vector<CWeapon> vwp;
public:
    
    CWeaponWarrior(int nId_, int nStrength_,int nForce_,int nCityNo_, 
        CHeadquarter * pHeadquarter_,int nWeaponNum ):
        CWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_),vwp(nWeaponNum)
        { }
    bool HasBomb() { 
        for(int i = 0; i < vwp.size();i ++)
            if( vwp[i].nKindNo == WEAPON_BOMB)
                return true;
        return false;
    }
    int GetSwordForce() {
        for(int i = 0; i < vwp.size();i ++)
            if( vwp[i].nKindNo == WEAPON_SWORD)
                return vwp[i].nForce;
        return 0;
    }
    int UseSword() {
        for(int i = 0; i < vwp.size();i ++)
            if( vwp[i].nKindNo == WEAPON_SWORD) {
                int nTmp = vwp[i].nForce;
                vwp[i].nForce *= 0.8;
                if( vwp[i].nForce == 0)
                    vwp.erase ( vwp.begin () + i);
                return nTmp;
            }
        return 0;
    }
    int ShootArrow()
    {
        for(vector<CWeapon>::iterator i = vwp.begin(); i != vwp.end();i ++)
            if( i->nKindNo == WEAPON_ARROW) {
                i->nForce --;
                if( i->nForce == 0)
                    vwp.erase(i);
                return CWeapon::nArrowForce;
            }
        return 0;
    }
    string ReportWeapons()
    {
        if( vwp.size() == 0)
            return "";
        string rs = " has ";
        sort(vwp.begin(),vwp.end());
        bool bFirst = true;
        for( int i = 0;i < vwp.size();i ++ ) {
            if( ! bFirst )             
                rs += ",";
            else 
                bFirst = false;
            rs += CWeapon::Names[vwp[i].nKindNo];    
            if( vwp[i].nKindNo != WEAPON_BOMB ) 
                rs += string("(") + MyIntToStr(vwp[i].nForce)+ ")";

        }
        return rs;
    }

};

class CNinja:public CWeaponWarrior
{
friend class CHeadquarter;
public:
    //CNinja constructor
    CNinja(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
        CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,2)
    {
        bool bDeleteSword = false;
        vector<CWeapon>::iterator p;
        for( int i = 0;i < 2;i ++) {
            vwp[i].nKindNo =( nId_ + i )% WEAPON_NUM;    
            if( vwp[i].nKindNo == WEAPON_SWORD ) {
                vwp[i].nForce = nForce_ * 0.2;
                if(vwp[i].nForce == 0) {
                    bDeleteSword = true;
                    p = vwp.begin() + i;
                }
            }
            else if( vwp[i].nKindNo == WEAPON_ARROW )
                vwp[i].nForce = 3;
        }
        if( bDeleteSword)
            vwp.erase (p);
    }

    virtual int  HurtedBy(CWarrior * pEnemy);
    virtual string GetName();
    bool VirtualFightback( CWarrior * pEnemy) {  return false; }

};
class CDragon:public CWeaponWarrior
{
friend class CHeadquarter;
private:
    double fMorale;
public:
    CDragon(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);
    virtual int Attack( CWarrior * p) ;
    void FightBack(CWarrior * pEnemy);
    virtual string GetName();
    void AddMorale(double a) { fMorale += a; };
};

class CLion:public CWarrior
{
    friend class CHeadquarter;
private:
    int nLoyalty;
public:
    static int nLoyaltyDec;
    CLion(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);
    int HurtedBy(CWarrior * pEnemy);
    void FightBack(CWarrior * pEnemy);
    int Attack( CWarrior * p) ;
    virtual string GetName();
    bool Runaway ()    {    return nLoyalty <= 0; }
};

class CIceman:public CWeaponWarrior
{
friend class CHeadquarter;
private:
    int nSteps;
public:
    //CIceman constructor    
    CIceman(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
        CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,1),nSteps(0)
    {
        vwp[0].nKindNo = nId % WEAPON_NUM;    
        if( vwp[0].nKindNo == WEAPON_SWORD ) {
            vwp[0].nForce = nForce_ * 0.2;
            if(  vwp[0].nForce == 0)
                vwp.clear();
        }
        else if( vwp[0].nKindNo == WEAPON_ARROW )
            vwp[0].nForce = 3;
    }
    virtual void March() ;
    virtual string GetName() ;
};

class CWolf:public CWeaponWarrior
{
friend class CHeadquarter;
private:
    int nEnemyKilled;
public:
    //CWolf Constructor
    CWolf(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
        CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,0),    nEnemyKilled(0)
    {
    }
    virtual int Attack( CWarrior * pEnemy);
    virtual string GetName() ;
    void EarnWeapons( CWarrior * pEnemy) ;
};

//cls CHeadQuarter
class CHeadquarter {

friend class CWarrior;
friend class CWolf;
friend class CDragon;
friend class CIceman;
friend class CLion;
friend class CNinja;
private:
    int nBloodMoney ; // 紀錄打仗贏后得到的
    int nMoney;
    int nEnemys;
    int nWarriorNo;
    list<CWarrior * > lstWarrior;
    int nColor;
    CKingdom * pKingdom;
    int nCityNo; //red: 0 ,blue nCitynum + 1
    CHeadquarter * pEnemyheadquarter;
    vector<CWarrior *> vAwardList;
public:
    static int MakingSeq[2][WARRIOR_NUM];
    CHeadquarter(int nColor_, int nMoney_,int nCityNo_ ) : nColor(nColor_), nWarriorNo(1),
                nEnemys(0),nMoney(nMoney_),nCityNo(nCityNo_),nBloodMoney(0)
    {
    }
    ~CHeadquarter()
    {
        list<CWarrior*> ::iterator p;
        for( p = lstWarrior.begin(); p != lstWarrior.end(); p ++ )
            delete (* p);
        lstWarrior.clear();
    }
    void SetEnemy( CHeadquarter * p)
    {
        pEnemyheadquarter = p;
    }
    void SetKingdom( CKingdom * p)
    {
        pKingdom = p;
    }
    void AddEvent( EEventType eType, int nCityNo, int nColor,const string & sEventString);
    void PrintMoney();
    string GetColorStr() 
    {
        if( nColor == COLOR_RED)
            return "red";
        else
            return "blue";
    }
    int GetColor()
    {
        return nColor;
    }
    void LionRunaway();
    void Bomb();
    void ShootArrow();
    void WarriorBorn();
    void AddToAwardList( CWarrior * pWarrior);
    void GiveAward();
    void WarriorsMarch(int nEnemyHeadquterCityNo );
    void WarriorsAttack();
    void WarriorsReport();
    void EnemyReach();
    void WarriorsGetFreeMoney(int);
    CWarrior * QueryCityWarrior( int nCityNo);
    void EarnBloodMoney( CWarrior * p, int nCityNo);
    //addfor 2010
    void AddBloodMoney() {
        nMoney += nBloodMoney;
        nBloodMoney = 0;
    }
    //gwend

    
};


class CCity 
{
private:
    int nFlagColor;
    int nNo;    
    int nLastWinWarriorColor;
public:
    int nMoney;
    CCity( ):nFlagColor(COLOR_NONE),nMoney(0),nLastWinWarriorColor(COLOR_NONE)
    {
    }
    //modifor 2010
    bool CWarriorWin( int nColor)  //返回是否要升旗子
    {
        if( nColor == nLastWinWarriorColor ) {        
            if( nFlagColor != nColor) {
                SetFlagColor(nColor);
                return true;
            }
            else
                return false;
        }
        nLastWinWarriorColor = nColor;
        return false;
    }

    void WarDraw()
    {
        nLastWinWarriorColor = COLOR_NONE;
    }
    void SetNo(int nNo_ ) 
    {
        nNo = nNo_;
    }
    //void Earthquake();
    void AddMoney() {
        nMoney += 10;
    }
    int MoneyTaken() {
        int nTmp = nMoney;
        nMoney = 0;
        return nTmp;
    }
    void SetFlagColor( int nColor)
    {
        nFlagColor = nColor;
    }
    int GetFlagColor() 
    {
        return nFlagColor;
    }
    int GetTotalMoney()
    {
        return nMoney;
    }

};

class CEvent
{
private:
    EEventType eEventType;
    int nTime;
    int nCityNo;
    int nColor;
    string sDescribe;
public:    
      CEvent(EEventType eEventType_,int nTime_,int nCityNo_,int nColor_, const string & s) :
        eEventType(eEventType_),nTime(nTime_),nCityNo(nCityNo_),nColor(nColor_),sDescribe(s) 
      {
      }
      void Output()  
      {
        char szTime[20];
        sprintf(szTime,"%03d:%02d",nTime /60, nTime % 60);
        cout << szTime << " " << sDescribe << endl;
      }
      bool operator < ( const CEvent & e2 ) const {
        if( nTime < e2.nTime )
            return true;
        else if( nTime > e2.nTime )
            return false;

        if( eEventType == e2.eEventType && eEventType == EVENT_WARRIOR_REPORT) {
            if( nColor < e2.nColor )
                return true;
            else if( nColor == e2.nColor) 
                return nCityNo < e2.nCityNo ;
            else
                return false;
        }

        if( nCityNo < e2.nCityNo )
            return true;
        else if( nCityNo > e2.nCityNo )
            return false;
        
        if( eEventType < e2.eEventType )
            return true;
        else if( eEventType > e2.eEventType )
            return false;
        if( nColor < e2.nColor )
            return true;
        else
            return false;
      }


};
class CKingdom 
{
    friend class CHeadquarter;
private:
    CHeadquarter Red, Blue;
    int nTimeInMinutes;
    vector<CEvent> vEvent;
    vector<CCity> vCity;
    int nEndTime;
    int nCityNum;
public:
    void Run(int T) {
        for( int t = 0; t <= T; t ++ ) { //modifor 2010 old: t < T
            if( TimePass(t) == 0)
                return ;
        }
    }
    CKingdom(int nCityNum_,int nInitMoney):
        nTimeInMinutes(0),Red(COLOR_RED,nInitMoney,0),Blue(COLOR_BLUE,nInitMoney,nCityNum_ + 1),
            nCityNum(nCityNum_), vCity(nCityNum_ + 1)
    {
        for( int i = 1; i <= nCityNum;i ++ )
            vCity[i].SetNo(i);
        Red.SetKingdom(this);
        Red.SetEnemy( &Blue);
        Blue.SetKingdom(this);
        Blue.SetEnemy( &Red);
        nEndTime = 3000000;
    }
    int TimePass(int nMinutes) ;
    string SysemTimeStr() 
    {
        char szTime[20];
        sprintf(szTime,"%03d:%02d",nTimeInMinutes /60, nTimeInMinutes % 60);
        return szTime;
    }
    void WarDraw( int nCityNo)
    {
        vCity[nCityNo].WarDraw();
    }
    void KWarriorWin( CWarrior * pWarrior)
    {
        int nCityNo = pWarrior->GetPosition();
        if( vCity[nCityNo].CWarriorWin( pWarrior->GetColor()) == true ) {
            //addfor 2010 要判斷是否已經有同顏色的旗子,有則不升旗

            string sEventString = pWarrior->GetColorStr() + " flag raised in city " + MyIntToStr( nCityNo);
            AddEvent(EVENT_FLAG, nCityNo, pWarrior->GetColor(),sEventString);
        }
    }
    int GetTime()
    {
        return nTimeInMinutes;    
    }
    void WarEnd()
    {
        if( nEndTime == 3000000)
            nEndTime = nTimeInMinutes;
    }
    void OutputResult()
    {
        sort(vEvent.begin(),vEvent.end());
        for( int i = 0;i < vEvent.size();i ++ )
            vEvent[i].Output();
    }
    void AddEvent( EEventType eType, int nCityNo, int nColor, const string & sEventString);
    //void CityEarthQuake( int nNo);
    int GetCityFlagColor( int nCityNo) 
    {
        return vCity[nCityNo].GetFlagColor();
    }
    int QueryCityMoney( int nNo) 
    {
        return vCity[nNo].GetTotalMoney();
    }
    void TakeCityMoney( int nNo)
    {
        vCity[nNo].MoneyTaken();
    }
};


//CWarrior functions
int CWarrior::GetColor() const
{
    return pHeadquarter->GetColor();
}
string CWarrior::GetColorStr()
{
    return pHeadquarter->GetColorStr();
}

bool CWarrior::VirtualFightback( CWarrior * pEnemy)
//假定能夠開始反擊
{
    if(nStrength > 0 && nForce /2 + GetSwordForce() >= pEnemy->nStrength )
        return true; //反擊敵人致死
    return false;
}
bool CWarrior::VirtualAttack( CWarrior * pEnemy)
{
    if( nStrength > 0 && nForce + GetSwordForce() >= pEnemy->nStrength )
        return true; //殺死敵人
    return false;
}


int CWarrior::Attack( CWarrior * pEnemy)
{
    if( pEnemy->GetStrength() <= 0) //敵人已經被箭射殺了
        return 1;
    
    char szTmp[200];
    sprintf(szTmp," with %d elements and force %d",nStrength,nForce);
    string sEventString = GetName() + " attacked " + 
        pEnemy->GetName() + string(" in city ") + MyIntToStr(nCityNo) + szTmp;// modifor 2010
    pHeadquarter->AddEvent( EVENT_ATTACK, nCityNo, GetColor(), sEventString);  
    if( pEnemy->HurtedBy(this) <= 0) { 
        return 1; //殺死敵人
    }
    if( nStrength <= 0 ) {
        Killed();
        return -1; //被反擊的敵人殺死
    }
    return 0;
}

int CWarrior::HurtedBy(CWarrior * pEnemy)
{
    int nSwordForce = pEnemy->UseSword(); 
    nStrength -= pEnemy->GetForce() + nSwordForce;
    if( nStrength <= 0 ) {
        Killed();
        return -1;
    }
    else {
        string sEventString = GetName() + " fought back against " + pEnemy->GetName() + " in city "  + MyIntToStr(nCityNo);
        FightBack(pEnemy);
        pHeadquarter->AddEvent(EVENT_FIGHTBACK,nCityNo, GetColor(),sEventString);
        return nStrength;
    }
}
void CWarrior::Killed() 
{
    string sEventString = GetName() + " was killed in city " + MyIntToStr(nCityNo);    
    pHeadquarter->AddEvent(EVENT_KILLED, nCityNo, GetColor(), sEventString);
}
void CWarrior::March() 
{
    if( GetColor() == COLOR_RED)
        nCityNo ++;
    else
        nCityNo --;

}
int CNinja::HurtedBy(CWarrior * pEnemy)
{
    int nSwordForce = pEnemy->UseSword(); 
    nStrength -= pEnemy->GetForce() + nSwordForce;
    if( nStrength <= 0 ) {
        Killed();
        return -1;
    }

    return nStrength;
}
string CNinja::GetName()
{
    return pHeadquarter->GetColorStr() + " ninja " + MyIntToStr(nId);
}


//CDragon Constructor
CDragon::CDragon(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
    CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,1)
{
        vwp[0].nKindNo = nId_ % WEAPON_NUM;    
        if( vwp[0].nKindNo == WEAPON_SWORD ) {
            vwp[0].nForce = nForce_ * 0.2;
            if(  vwp[0].nForce == 0)
                vwp.clear();
        }
        else if( vwp[0].nKindNo == WEAPON_ARROW )
            vwp[0].nForce = 3;
        fMorale = pHeadquarter -> nMoney /(double)CWarrior::InitialLifeValue [0];
}

int CDragon::Attack( CWarrior * p) 
{
    int nRetVal = CWarrior::Attack(p);
    
    if( nRetVal != -1 && fMorale > 0.8) { //沒有戰死
        string sEventString = GetName() + " yelled in city " + MyIntToStr(nCityNo);
        pHeadquarter->AddEvent( EVENT_YELL, nCityNo, GetColor(), sEventString);
        if( nRetVal == 0) //平局
            fMorale -= 0.2;
        else
            fMorale += 0.2;
    }
    return nRetVal;
}
void CDragon::FightBack(CWarrior * pEnemy)
{
    CWarrior::FightBack (pEnemy);
    if( pEnemy->GetStrength() > 0 )
        fMorale -= 0.2;
    else
        fMorale += 0.2;
}

string CDragon::GetName() 
{
    return pHeadquarter->GetColorStr() + " dragon " + MyIntToStr(nId); 
}
//CLion Constructor
CLion::CLion(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
    CWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_)
{
    nLoyalty = pHeadquarter ->nMoney;
}
int CLion::Attack( CWarrior * p) 
{    
    int nTmp = nStrength;
    int nRetVal = CWarrior::Attack(p);
    if( nRetVal == -1)  //被敵人反擊殺死
        p->SetStrength (p->GetStrength () + nTmp);
    else if( nRetVal != 1 ) //未能殺死敵人
        nLoyalty -= CLion::nLoyaltyDec ;
    return nRetVal;
}
void CLion::FightBack(CWarrior * pEnemy)
{
    
    CWarrior::FightBack (pEnemy);
    if( pEnemy->GetStrength() > 0 )
        nLoyalty -= CLion::nLoyaltyDec ;
}


int CLion::HurtedBy(CWarrior * pEnemy)
//此處實現生命向敵人轉移
{
    int nSwordForce = pEnemy->UseSword();
    if( nStrength - pEnemy->GetForce() - nSwordForce <= 0 ) {
        pEnemy->SetStrength( pEnemy->GetStrength() + nStrength ); 
        nStrength = 0; 
        Killed();
        return -1;
    }
    nStrength -= pEnemy->GetForce() + nSwordForce;
    string sEventString = GetName() + " fought back against " + pEnemy->GetName() + " in city "  + MyIntToStr(nCityNo);
    FightBack(pEnemy);
    pHeadquarter->AddEvent(EVENT_FIGHTBACK,nCityNo, GetColor(),sEventString);
    return nStrength;
}
string CLion::GetName() 
{
    return pHeadquarter->GetColorStr() + " lion " + MyIntToStr(nId); 
}



void CIceman::March() 
{
    CWarrior::March();
    nSteps = ( nSteps + 1 ) %2;
    if( nSteps ==  0) {
        if( nStrength - 9 > 1 ) 
            nStrength -= 9;
        else
            nStrength = 1;
        nForce += 20;
    }
}
string CIceman::GetName() 
{
    return pHeadquarter->GetColorStr() + " iceman " + MyIntToStr(nId); 
}

void CWolf::EarnWeapons( CWarrior * pEnemy) 
{
    int i,j;
    if( pEnemy->ReportWeapons() != "") {
        CWeaponWarrior * p = ( CWeaponWarrior *) pEnemy;
        for(i = 0;i < p->vwp.size(); i ++ ) {
            bool bAlreadyHas = false;
            for( j = 0; j < vwp.size(); j ++ ) {
                if( p->vwp[i].nKindNo == vwp[j].nKindNo ) {
                    bAlreadyHas = true;
                    break;
                }
            }
            if( ! bAlreadyHas)
                vwp.push_back ( p->vwp[i]);
        }
    }
}

int CWolf::Attack( CWarrior * pEnemy)
{
    int nEnemyStrength = pEnemy->GetStrength();
    int nOriStrength = nStrength;
    int nRetVal = CWarrior::Attack(pEnemy);
    if( nRetVal > 0 )   //殺死敵人 
        EarnWeapons( pEnemy);
    return nRetVal;
}
string CWolf::GetName() 
{
    return pHeadquarter->GetColorStr() + " wolf " + MyIntToStr(nId); 
}

//CHeadquarter functions

void CHeadquarter::LionRunaway()
{
    
    string sEventString;
    list<CWarrior * >::iterator i = lstWarrior.begin();
    while(i != lstWarrior.end() ) {
        if( (*i)->Runaway()) {
        //輸出樣例: 000:05 blue lion 1 ran away 
            int nCityNo = ( * i )->GetPosition();
            if( nColor == COLOR_RED &&  nCityNo == pKingdom->nCityNum + 1 ||
                nColor == COLOR_BLUE &&  nCityNo == 0 ) 
                continue;
            sEventString = (*i)->GetName() + " ran away";
            AddEvent( EVENT_LION_RUN, ( * i )-> nCityNo, nColor,sEventString); 
            i = lstWarrior.erase (i); //指向被erased的元素的后一個
            continue;
        }
        i ++;
    }
}
void CHeadquarter::Bomb()
{
    list<CWarrior * >::iterator i = lstWarrior.begin();
    while( i != lstWarrior.end() ) { 
        int nCityNo = ( * i )->GetPosition();
        if( (*i)->GetStrength () > 0 ) {
            CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
            if( p ) {
                bool bShouldAttack = false;
                if( pKingdom->GetCityFlagColor(nCityNo) == nColor )
                    bShouldAttack = true;
                else if( pKingdom->GetCityFlagColor(nCityNo) == COLOR_NONE) {
                    if( nColor == COLOR_RED && (nCityNo % 2 == 1))
                        bShouldAttack = true;
                    if( nColor == COLOR_BLUE && (nCityNo % 2 == 0))
                        bShouldAttack = true;
                }
                bool r1 = false ,r2 = false;
                if( ( * i )->HasBomb()) {
                    if( bShouldAttack) {
                        if( (*i)->VirtualAttack(p) == false)
                            r1 = p->VirtualFightback(*i);
                        else
                            r1 = false;
                    }
                    else
                        r2 = p->VirtualAttack(*i);
                    if( r1  || r2  ) { //會被敵人反擊殺死或被敵人主動攻擊殺死 
                        //輸出樣例: 000:38 blue dragon 1 used a bomb and killed red lion 7
                        //string sEventString = (*i)->GetName() + " used a bomb and killed " + 
                        //    p->GetName() + string(" in city ") + MyIntToStr(nCityNo);
                        string sEventString = (*i)->GetName() + " used a bomb and killed " + 
                            p->GetName();
                        AddEvent( EVENT_BOMB, nCityNo, GetColor(), sEventString);  
                        i = lstWarrior.erase (i); //指向被erased的元素的后一個
                        p->SetStrength(0);
                        continue;
                    }
                }
            }
        }
        i ++;
    }
}
void CHeadquarter::ShootArrow()
{
    list<CWarrior * >::iterator i;
    for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) { 
        int nCityNo = ( * i )->GetPosition();
        if( nColor == COLOR_RED ) {
            nCityNo ++;
            if( nCityNo == pKingdom->nCityNum + 1 )
                continue ;
        }
        else {
            nCityNo --;
            if( nCityNo == 0)
                continue;
        }
        CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
        if( p ) {
            int nArrowForce = (*i)->ShootArrow();
            if( nArrowForce > 0) {
                string sEventString = (*i)->GetName() + " shot";
    //輸出樣例: 000:38 blue dragon 1 used a bomb and killed red lion 7
                if( p->AttackedByArrow(nArrowForce) <= 0 ) 
                    //sEventString += " and killed " + p->GetName() + string(" in city ") + MyIntToStr(nCityNo);
                    sEventString += " and killed " + p->GetName();
                AddEvent( EVENT_ARROW,( * i )->GetPosition(), GetColor(), sEventString);  
            }
        }
    }
    
}
int CKingdom::TimePass(int nMinutes) {
    int i;
    nTimeInMinutes = nMinutes;
    if( nTimeInMinutes > nEndTime )
        return 0;
    int nRemain = nTimeInMinutes % 60;
    switch( nRemain) {
        case 0: //生產怪物
            Red.WarriorBorn();
            Blue.WarriorBorn();
            break;
        case 5: //lion可能逃跑
            Red.LionRunaway();
            Blue.LionRunaway();
            break;
        case 10: //前進
            Red.WarriorsMarch(nCityNum + 1);
            Blue.WarriorsMarch(0);
            break;
        case 20: //城市出產生命元
            
            for( i = 0;i < vCity.size();i ++ ) {
                vCity[i].AddMoney();
            }
            break;
        case 30: //掙錢
            Red.WarriorsGetFreeMoney(nCityNum+1); 
            Blue.WarriorsGetFreeMoney(nCityNum+1);

            break;
        case 35: //放箭
            Red.ShootArrow();
            Blue.ShootArrow();
            break;
        case 38:
            Red.Bomb();
            Blue.Bomb();
            break;
        case 40://發生戰斗
            //addfor debug cccc
            if( nTimeInMinutes == 1720 )
                cout << "" ;
            //gwend

            Red.WarriorsAttack();
            Blue.WarriorsAttack();
            Red.GiveAward();
            Blue.GiveAward();
            Red.AddBloodMoney();
            Blue.AddBloodMoney();
            break;
        case 50:
            Red.PrintMoney(); //addfor 2010
            Blue.PrintMoney(); //addfor 2010
            break;
        case 55:
            Red.WarriorsReport();
            Blue.WarriorsReport();
    }
    return 1;
}
void CHeadquarter::EnemyReach()
{
    nEnemys ++;
    if( nEnemys == 2 ) {
        if( nColor == COLOR_RED ) 
            AddEvent( EVENT_CITYTAKEN, nCityNo,    nColor,string("red headquarter was taken"));
        else
            AddEvent( EVENT_CITYTAKEN, nCityNo, nColor,string("blue headquarter was taken"));
        pKingdom->WarEnd();
    }
}

CWarrior * CHeadquarter::QueryCityWarrior( int nCityNo)
{
    list<CWarrior *>::iterator i;
    for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) {
        if( (* i )->GetPosition () == nCityNo)
            return ( * i );
    }
    return NULL;
}
void CHeadquarter::WarriorsGetFreeMoney(int nEnemyheadquarterNo )
//武士拿城市里的錢,在沒有發生戰斗的情況下
{
    list<CWarrior*>::iterator i;
    for( i = lstWarrior.begin(); i !=  lstWarrior.end();i ++ ) {
        int nCityno = ( * i )->GetPosition();
        if( nCityno != 0 && nCityno != nEnemyheadquarterNo) {
            CWarrior * p ;
            p = pEnemyheadquarter->QueryCityWarrior(nCityno);
            if( p == NULL ) { 
                int nMoneyEarned;
                nMoneyEarned = pKingdom->QueryCityMoney(nCityno);
                if( nMoneyEarned > 0 ) {
                    nMoney += nMoneyEarned;
                    pKingdom->TakeCityMoney(nCityno);
                    string sEventString = (*i)->GetName() + " earned " + MyIntToStr(nMoneyEarned) + " elements for his headquarter";
                    AddEvent( EVENT_EARNMONEY, nCityno,nColor, sEventString);
                }
            }
        }
    }
}
void CHeadquarter::WarriorsMarch(int nEnemyHeadquterCityNo)
{
    list<CWarrior * >::iterator i;
    string sEventString;
    for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) {
        int nOldPos = ( * i ) ->nCityNo ;
        if( nColor == COLOR_RED ) {
            if( ( * i )-> nCityNo < nEnemyHeadquterCityNo)
                ( *i )->March();
        }
        else {
            if( ( * i )-> nCityNo > nEnemyHeadquterCityNo)
                ( *i )->March();
        }
        char szTmp[100];
        sprintf( szTmp," with %d elements and force %d",(*i)->nStrength,(*i)->nForce);

        if( nOldPos != nEnemyHeadquterCityNo) {
            if (( * i )-> nCityNo == nEnemyHeadquterCityNo ) {
                sEventString = (*i)->GetName() + " reached "+  pEnemyheadquarter->GetColorStr() + " headquarter" + szTmp;
                AddEvent( EVENT_REACH, ( * i )-> nCityNo, nColor,sEventString);
                pEnemyheadquarter->EnemyReach();
            }
            else {
                sEventString = (*i)->GetName() + " marched to city " + MyIntToStr(( * i )->GetPosition() ) + szTmp;
                AddEvent( EVENT_MARCH, ( * i )->GetPosition(), nColor,sEventString);
            }
        }
    }
}

void CHeadquarter::WarriorsReport()
{
    list<CWarrior * >::iterator i = lstWarrior.begin();
    string sEventString;
    while(i != lstWarrior.end()) {
        if( (*i)->nStrength <= 0) { //在35分,或剛才的戰斗中已經被殺了
            i = lstWarrior.erase (i);
            continue;
        }
        string sEventString = (*i)->GetName();
        string sWeaponStatus = (*i)->ReportWeapons();
        if( sWeaponStatus != "") 
            sEventString += sWeaponStatus;
        else
            sEventString += " has no weapon";
        AddEvent( EVENT_WARRIOR_REPORT, ( * i )-> nCityNo, nColor,sEventString );
        i ++;
    }
}
void CHeadquarter::WarriorsAttack()
    {
    list<CWarrior * >::iterator i = lstWarrior.begin();
    for( i; i != lstWarrior.end();i ++) { //循環執行過程中有可能導致 lstWarrior中的某些元素被刪,那么 這可能就有問題了 下面
        if( (*i)->nStrength <= 0) //5分鍾前已經被射殺
            continue;
        int nCityNo = ( * i )->GetPosition();
        //addfor debug
        if( nCityNo == 13 )
            cout << "";
        //gwend
        CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
        if( p ) {
            bool bShouldAttack = false;
            if( pKingdom->GetCityFlagColor(nCityNo) == nColor )
                bShouldAttack = true;
            else if( pKingdom->GetCityFlagColor(nCityNo) == COLOR_NONE) {
                if( nColor == COLOR_RED && (nCityNo % 2 == 1))
                    bShouldAttack = true;
                if( nColor == COLOR_BLUE && (nCityNo % 2 == 0))
                    bShouldAttack = true;
            } //有可能反擊殺死敵方,然后換旗,結果到這里又主動進攻了
            if( bShouldAttack && ( p->GetStrength () > 0 || p->bShotToDeath )) {
                int nResult = ( * i )->Attack (p);
                    if( nResult == 1 ) { //殺死敵人
//由於lsWarrior里面的順序就是 離敵人近的在前面,所以可以直接這里就獎勵了(不行,因為還有反擊殺死敵人的情況)
                    AddToAwardList(*i);
                    pKingdom->KWarriorWin( * i ) ; //讓kingdom處理城市變旗幟的事情
                    EarnBloodMoney( (*i), nCityNo); 
                }
                else if( nResult < 0 ) { //被敵人反擊時殺死
                    pEnemyheadquarter->AddToAwardList(p);
                    pKingdom->KWarriorWin(p); //讓kingdom處理城市變旗幟的事情
                    pEnemyheadquarter->EarnBloodMoney(p,nCityNo);
                    /*
                    i = lstWarrior.erase (i); //指向被erased的元素的后一個
                    continue;
                    erase 統一在report時完成
                    */
                }
                else {
                    pKingdom->WarDraw(nCityNo);
                }
            } 
            else { //如果不是主動進攻,但是敵人已經被箭射殺,那么還算發生了戰斗,而且會影響Dragon的fMorale
                    //還會影響Wolf繳獲武器
                if( p->bShotToDeath ) { //5分鍾前被箭射殺
                    AddToAwardList(*i);
                    pKingdom->KWarriorWin( * i ) ; //讓kingdom處理城市變旗幟的事情
                    EarnBloodMoney( (*i), nCityNo); 
                    (*i) -> AddMorale(0.2);
                    (*i) -> EarnWeapons(p);
                }
            }
        }
    }
}
void CHeadquarter::EarnBloodMoney( CWarrior * p, int nCityNo)
{
//獲取殺死敵人以后的城市中的生命元
    int nMoneyEarned;
    nMoneyEarned = pKingdom->QueryCityMoney(nCityNo);
    if( nMoneyEarned > 0 ) {
        nBloodMoney += nMoneyEarned;
        pKingdom->TakeCityMoney(nCityNo);
        string sEventString = p->GetName() + " earned " + MyIntToStr(nMoneyEarned) + " elements for his headquarter";
        AddEvent( EVENT_EARNMONEY, nCityNo,nColor, sEventString);
    }
}
bool MyCompare(  const PWARRIOR & p1, const PWARRIOR & p2)
{

    if( p1->GetColor() == COLOR_RED) 
        return p1->nCityNo > p2->nCityNo;
    else
        return p1->nCityNo < p2->nCityNo;
}
void CHeadquarter::GiveAward()
{
    
    int nSize = vAwardList.size();
    sort(vAwardList.begin(), vAwardList.end(),MyCompare);
    for( int i = 0;i < vAwardList.size();i ++ ) {
        if( nMoney >= 8 ) {
            vAwardList[i]->nStrength += 8;
            //addfor debug
            CWarrior * tmp =  vAwardList[i];
            int nStrength = tmp->nStrength ;
            int nForce = tmp->nForce ;
            int nCityNo = tmp->nCityNo; 
            int nId = tmp->nId ;
            //gwend
            nMoney -= 8;
        }
        else
            break;
    }
    vAwardList.clear();
}

void CHeadquarter::AddToAwardList( CWarrior * pWarrior)
{
    vAwardList.push_back(pWarrior);
}
void CHeadquarter::AddEvent( EEventType eType, int nCityNo, int nColor, const string & sEventString)
{
    pKingdom->AddEvent( eType,nCityNo,nColor,sEventString);    
}
void CHeadquarter::PrintMoney() //addfor 2010
{        
        char szTmp[100];
        
        sprintf(szTmp,"%d",nMoney);
        string sEventString = string(szTmp) + " elements in " + GetColorStr() + " headquarter";
        if( nColor == COLOR_RED)  
            pKingdom->AddEvent( EVENT_PRINTMONEY, 0, nColor,sEventString);
        else 
            pKingdom->AddEvent( EVENT_PRINTMONEY, pKingdom->vCity.size() + 1, nColor,sEventString);
}
void CHeadquarter::WarriorBorn()
{

    CWarrior * p = NULL;
    int nSeqIdx = (nWarriorNo - 1) % 5;
    if( nMoney <  CWarrior::InitialLifeValue[MakingSeq[nColor][nSeqIdx]])
        return ;
    nMoney -= CWarrior::InitialLifeValue[MakingSeq[nColor][nSeqIdx]];
    int nKindNo = MakingSeq[nColor][nSeqIdx];
    
    switch( nKindNo ) {
        case DRAGON:
            p = new CDragon(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitalForce[nKindNo],nCityNo, this);
            break;
        case NINJA:
            p = new CNinja(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitalForce[nKindNo],nCityNo, this);
            break;
        case ICEMAN:
            p = new CIceman(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitalForce[nKindNo],nCityNo, this);
            break;
        case LION:
            p = new CLion(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitalForce[nKindNo],nCityNo, this);
            break;
        case WOLF:
            p = new CWolf(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitalForce[nKindNo],nCityNo, this);
            break;
    }
    
    lstWarrior.push_back(p);
    string sEventString = p->GetName () + " born";
    if( nKindNo == LION )
        sEventString += "\nIts loyalty is " + MyIntToStr(((CLion*)p)->nLoyalty);
    else if( nKindNo == DRAGON) {
        char szTmp[40];
        //old sprintf(szTmp,"%.2f",((CDragon*)p)->fMorale + EPS);
        sprintf(szTmp,"%.2f",((CDragon*)p)->fMorale );
        sEventString += "\nIts morale is " +string(szTmp);
    }

    pKingdom->AddEvent( EVENT_BORN, nCityNo, nColor,sEventString);
    nWarriorNo ++;
} 

void CKingdom::AddEvent( EEventType eType, int nCityNo,int nColor, const string & sEventString)
{
    CEvent tmp(eType, nTimeInMinutes, nCityNo,nColor,sEventString);
    vEvent.push_back(tmp);
    //addfor debug
    //tmp.Output();
    //gwend

}
const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow" };
const char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];    
int CWarrior::InitalForce [WARRIOR_NUM];
int CWeapon::nArrowForce;
int CLion::nLoyaltyDec;
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };
int main()
{
    int nCases;
    int M,N,R,K,T;
    //freopen("f:\\mydoc\\程序設計實習\\warcraft\\war3\\warcraft.in","r",stdin);
    //freopen("f:\\mydoc\\程序設計實習\\warcraft\\war3\\6.in","r",stdin);
    cin >> nCases;
    int nCaseNo = 1;
    while( nCases -- )  {
        cin >> M >> N >> R >> K >> T;
        CWeapon::nArrowForce = R;
        CLion::nLoyaltyDec = K;
    //第二行:五個整數,依次是 dragon 、NINJA、iceman、lion、wolf 的初始生命值。它們都大於0小於等於100
        int i;
        for( i = 0;i < WARRIOR_NUM;i ++ )
            cin >> CWarrior::InitialLifeValue[i];
        for( i = 0;i < WARRIOR_NUM;i ++ )
            cin >> CWarrior::InitalForce[i];
        CKingdom MyKingdom(N,M);
        MyKingdom.Run(T);
        cout << "Case " << nCaseNo++ << ":" << endl;
        MyKingdom.OutputResult();
    }    
    return 0;
}
View Code

  2022.1 魔獸世界之三的題目:

045:魔獸世界三(開戰)

描述
魔獸世界的西面是紅魔軍的司令部,東面是藍魔軍的司令部。兩個司令部之間是依次排列的若干城市,城市從西向東依次編號為1,2,3 .... N ( N <= 20)。紅魔軍的司令部算作編號為0的城市,藍魔軍的司令部算作編號為N+1的城市。司令部有生命元,用於制造武士。


兩軍的司令部都會制造武士。武士一共有dragon 、ninja、iceman、lion、wolf 五種。每種武士都有編號、生命值、攻擊力這三種屬性。


雙方的武士編號都是從1開始計算。紅方制造出來的第n 個武士,編號就是n。同樣,藍方制造出來的第n 個武士,編號也是n。


武士在剛降生的時候有一個初始的生命值,生命值在戰斗中會發生變化,如果生命值減少到0(生命值變為負數時應當做變為0處理),則武士死亡(消失)。

武士可以擁有武器。武器有三種,sword, bomb,和arrow,編號分別為0,1,2。

sword的攻擊力是使用者當前攻擊力的20%(去尾取整)。

bomb的攻擊力是使用者當前攻擊力的40%(去尾取整),但是也會導致使用者受到攻擊,對使用者的攻擊力是對敵人取整后的攻擊力的1/2(去尾取整)。Bomb一旦使用就沒了。

arrow的攻擊力是使用者當前攻擊力的30%(去尾取整)。一個arrow用兩次就沒了。



武士降生后就朝對方司令部走,在經過的城市如果遇到敵人(同一時刻每個城市最多只可能有1個藍武士和一個紅武士),就會發生戰斗。戰斗的規則是:

在奇數編號城市,紅武士先發起攻擊

在偶數編號城市,藍武士先發起攻擊

戰斗開始前,雙方先對自己的武器排好使用順序,然后再一件一件地按順序使用。編號小的武器,排在前面。若有多支arrow,用過的排在前面。排好序后,攻擊者按此排序依次對敵人一件一件地使用武器。如果一種武器有多件,那就都要用上。每使用一件武器,被攻擊者生命值要減去武器攻擊力。如果任何一方生命值減為0或小於0即為死去。有一方死去,則戰斗結束。

雙方輪流使用武器,甲用過一件,就輪到乙用。某一方把自己所有的武器都用過一輪后,就從頭開始再用一輪。如果某一方沒有武器了,那就挨打直到死去或敵人武器用完。武器排序只在戰斗前進行,戰斗中不會重新排序。

如果雙方武器都用完且都還活着,則戰斗以平局結束。如果雙方都死了,也算平局。

有可能由於武士自身攻擊力太低,而導致武器攻擊力為0。攻擊力為0的武器也要使用。如果戰斗中雙方的生命值和武器的狀態都不再發生變化,則戰斗結束,算平局。

戰斗的勝方獲得對方手里的武器。武士手里武器總數不超過10件。繳獲武器時,按照武器種類編號從小到大繳獲。如果有多件arrow,優先繳獲沒用過的。

如果戰斗開始前雙方都沒有武器,則戰斗視為平局。如果先攻擊方沒有武器,則由后攻擊方攻擊。

不同的武士有不同的特點。

編號為n的dragon降生時即獲得編號為n%3 的武器。dragon在戰斗結束后,如果還沒有戰死,就會歡呼。


編號為n的ninjia降生時即獲得編號為n%3 和(n+1)%3的武器。ninja 使用bomb不會讓自己受傷。


編號為n的iceman降生時即獲得編號為n%3 的武器。iceman每前進一步,生命值減少10%(減少的量要去尾取整)。


編號為n的lion降生時即獲得編號為n%3 的武器。lion 有“忠誠度”這個屬性,其初始值等於它降生之后其司令部剩余生命元的數目。每前進一步忠誠度就降低K。忠誠度降至0或0以下,則該lion逃離戰場,永遠消失。但是已經到達敵人司令部的lion不會逃跑。lion在己方司令部可能逃跑。


wolf降生時沒有武器,但是在戰斗開始前會搶到敵人編號最小的那種武器。如果敵人有多件這樣的武器,則全部搶來。Wolf手里武器也不能超過10件。如果敵人arrow太多沒法都搶來,那就先搶沒用過的。如果敵人也是wolf,則不搶武器。


以下是不同時間會發生的不同事件:


在每個整點,即每個小時的第0分, 雙方的司令部中各有一個武士降生。


紅方司令部按照iceman、lion、wolf、ninja、dragon 的順序制造武士。


藍方司令部按照lion、dragon、ninja、iceman、wolf 的順序制造武士。


制造武士需要生命元。


制造一個初始生命值為m 的武士,司令部中的生命元就要減少m 個。


如果司令部中的生命元不足以制造某本該造的武士,那就從此停止制造武士。


在每個小時的第5分,該逃跑的lion就在這一時刻逃跑了。


在每個小時的第10分:所有的武士朝敵人司令部方向前進一步。即從己方司令部走到相鄰城市,或從一個城市走到下一個城市。或從和敵軍司令部相鄰的城市到達敵軍司令部。


在每個小時的第35分:在有wolf及其敵人的城市,wolf要搶奪對方的武器。


在每個小時的第40分:在有兩個武士的城市,會發生戰斗。


在每個小時的第50分,司令部報告它擁有的生命元數量。


在每個小時的第55分,每個武士報告其擁有的武器情況。


武士到達對方司令部后就算完成任務了,從此就呆在那里無所事事。


任何一方的司令部里若是出現了敵人,則認為該司令部已被敵人占領。

任何一方的司令部被敵人占領,則戰爭結束。戰爭結束之后就不會發生任何事情了。


給定一個時間,要求你將從0點0分開始到此時間為止的所有事件按順序輸出。事件及其對應的輸出樣例如下:


1) 武士降生

輸出樣例:000:00 blue dragon 1 born

表示在0點0分,編號為1的藍魔dragon武士降生


如果造出的是lion,那么還要多輸出一行,例:

000:00 blue lion 1 born

Its loyalty is 24

表示該lion降生時的忠誠度是24


2) lion逃跑

輸出樣例:000:05 blue lion 1 ran away

表示在0點5分,編號為1的藍魔lion武士逃走


3) 武士前進到某一城市


輸出樣例:



000:10 red iceman 1 marched to city 1 with 20 elements and force 30

表示在0點10分,紅魔1號武士iceman前進到1號城市,此時他生命值為20,攻擊力為30

對於iceman,輸出的生命值應該是變化后的數值


4) wolf搶敵人的武器

000:35 blue wolf 2 took 3 bomb from red dragon 2 in city 4

表示在0點35分,4號城市中,紅魔1號武士wolf 搶走藍魔2號武士dragon 3個bomb。為簡單起見,武器不寫復數形式


5) 報告戰斗情況

戰斗只有3種可能的輸出結果:


000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements

表示在0點40分,1號城市中,紅魔1號武士iceman 殺死藍魔12號武士lion后,剩下生命值20


000:40 both red iceman 1 and blue lion 12 died in city 2

注意,把紅武士寫前面

000:40 both red iceman 1 and blue lion 12 were alive in city 2

注意,把紅武士寫前面


6) 武士歡呼

輸出樣例:003:40 blue dragon 2 yelled in city 4


7) 武士抵達敵軍司令部

輸出樣例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30

(此時他生命值為20,攻擊力為30)對於iceman,輸出的生命值和攻擊力應該是變化后的數值


8) 司令部被占領

輸出樣例:003:10 blue headquarter was taken


9)司令部報告生命元數量

000:50 100 elements in red headquarter

000:50 120 elements in blue headquarter

表示在0點50分,紅方司令部有100個生命元,藍方有120個


10)武士報告情況

000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements

為簡單起見,武器都不寫復數形式。elements一律寫復數,哪怕只有1個


交代武器情況時,次序依次是:sword,bomb, arrow。


輸出事件時:


首先按時間順序輸出;

同一時間發生的事件,按發生地點從西向東依次輸出. 武士前進的事件, 算是發生在目的地。

在一次戰斗中有可能發生上面的 56 號事件。這些事件都算同時發生,其時間就是戰斗開始時間。一次戰斗中的這些事件,序號小的應該先輸出。

兩個武士同時抵達同一城市,則先輸出紅武士的前進事件,后輸出藍武士的。

對於同一城市,同一時間發生的事情,先輸出紅方的,后輸出藍方的。

顯然,8號事件發生之前的一瞬間一定發生了7號事件。輸出時,這兩件事算同一時間發生,但是應先輸出7號事件

雖然任何一方的司令部被占領之后,就不會有任何事情發生了。但和司令部被占領同時發生的事件,全都要輸出。



輸入
第一行是t,代表測試數據組數

每組樣例共三行。

第一行,4個整數 M,N,K, T。其含義為:
每個司令部一開始都有M個生命元( 1 <= M <= 100000)
兩個司令部之間一共有N個城市( 1 <= N <= 20 )
lion每前進一步,忠誠度就降低K。(0<=K<=100)
要求輸出從0時0分開始,到時間T為止(包括T) 的所有事件。T以分鍾為單位,0 <= T <= 6000

第二行:五個整數,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它們都大於0小於等於200

第三行:五個整數,依次是 dragon 、ninja、iceman、lion、wolf 的攻擊力。它們都大於0小於等於200
輸出
對每組數據,先輸出一行:

Case n:

如對第一組數據就輸出 Case 1:

然后按恰當的順序和格式輸出到時間T為止發生的所有事件。每個事件都以事件發生的時間開頭,時間格式是“時: 分”,“時”有三位,“分”有兩位。
樣例輸入
1
20 1 10 400
20 20 30 10 20
5 5 5 5 5
樣例輸出
Case 1:
000:00 blue lion 1 born
Its loyalty is 10
000:10 blue lion 1 marched to city 1 with 10 elements and force 5
000:50 20 elements in red headquarter
000:50 10 elements in blue headquarter
000:55 blue lion 1 has 0 sword 1 bomb 0 arrow and 10 elements
001:05 blue lion 1 ran away
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
002:50 20 elements in red headquarter
002:50 10 elements in blue headquarter
003:50 20 elements in red headquarter
003:50 10 elements in blue headquarter
004:50 20 elements in red headquarter
004:50 10 elements in blue headquarter
005:50 20 elements in red headquarter
005:50 10 elements in blue headquarter
提示
請注意浮點數精度誤差問題。OJ上的編譯器編譯出來的可執行程序,在這方面和你電腦上執行的程序很可能會不一致。5 * 0.3 的結果,有的機器上可能是 15.00000001,去尾取整得到15,有的機器上可能是14.9999999,去尾取整后就變成14。因此,本題不要寫 5 * 0.3,要寫 5 * 3 / 10
View Code
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<typeinfo>
using namespace std;
 
int soldier_HP[5];
char soldier_name[5][20] = {"iceman", "lion", "wolf", "ninja", "dragon"};
char weapon_name[3][20] = {"sword", "bomb", "arrow"};
int soldier_force[5];
int city_number, time_limited;
 
//different soldier class
//model class
class csoldier
{
public:
    int HP, force, locate, id;
    int weapon[4];
    int weapen_amount;
    csoldier() { memset(weapon, 0, sizeof(weapon)); }
    virtual ~csoldier(){}
 
//第n次交手應該使用的武器,n已經考慮過經過循環處理
    int getweapon(int &n)
    {
        bool flag = false;
        if (weapen_amount <= n) flag = true;
        if (n <= weapon[0])
        {
            ++n;
            if(flag) n = 1;
            return 0;
        }
        else if (n <= weapon[0] + weapon[1])
        {
            weapon[1]--;
            weapen_amount--;
            if(flag) n = 1;
            return 1;
        }
        else if (n <= weapon[3] + weapon[0] + weapon[1])
        {
            weapon[3]--;
            weapen_amount--;
            if(flag) n = 1;
            return 2;
        }
        else if (n <= weapen_amount)
        {
 
            weapon[2]--;
            weapon[3]++;
            ++n;
            if(flag) n = 1;
            return 2;
        }
        cout << "wrong!" << endl;
    }
    virtual void out_name() = 0;
    friend class battlefield;
};
 
class dragon:public csoldier
{
private:
    friend class battlefield;
    //constructor
    dragon(int n, int color):csoldier()
    {
        weapon[n % 3] = 1;
        weapen_amount = 1;
        force = soldier_force[4];
        locate = ((color == 0)? 0 : city_number + 1);
        HP = soldier_HP[4];
        id = n;
    }
    //destructor
    ~dragon(){}
    virtual void out_name()
    {
        cout << "dragon " << id;
    }
};
 
class ninja:public csoldier
{
private:
    friend class battlefield;
    ninja(int n, int color) :csoldier()
    {
        weapon[n % 3] = 1;
        weapon[(n + 1) % 3] = 1;
        weapen_amount = 2;
        force = soldier_force[3];
        locate = ((color == 0) ? 0 : city_number + 1);
        HP = soldier_HP[3];
        id = n;
    }
    ~ninja(){}
    virtual void out_name()
    {
        cout << "ninja " << id;
    }
};
 
class iceman:public csoldier
{
private:
    friend class battlefield;
    iceman(int n, int color) :csoldier()
    {
        weapon[(n % 3)] = 1;
        weapen_amount = 1;
        force = soldier_force[0];
        locate = ((color == 0) ? 0 : city_number + 1);
        HP = soldier_HP[0];
        id = n;
    }
    virtual void out_name()
    {
        cout << "iceman " << id;
    }
};
 
class lion:public csoldier
{
private:
    friend class battlefield;
    int loyalty;
    lion(int n, int color, int hp) :csoldier(), loyalty(hp)
    {
        weapon[n % 3] = 1;
        weapen_amount = 1;
        force = soldier_force[1];
        locate = ((color == 0) ? 0 : city_number + 1);
        HP = soldier_HP[1];
        id = n;
        cout << "Its loyalty is " << loyalty << endl;
    }
    virtual void out_name()
    {
        cout << "lion " << id;
    }
public:
    static int K;
};
int lion::K = 0;
 
class wolf:public csoldier
{
    wolf(int n, int color) :csoldier()
    {
        weapen_amount = 0;
        force = soldier_force[2];
        locate = ((color == 0) ? 0 : city_number + 1);
        HP = soldier_HP[2];
        id = n;
    }
    virtual void out_name()
    {
        cout << "wolf " << id;
    }
private:
    friend class battlefield;
};
 
class battlefield
{
private:
    int hour, minute, soldier_total[2], cur[2];
    int HP[2];
    char name[2][20];
    bool produce_end[2];//if production is carrying on, it is false, if else it is true
    csoldier ***head;
    int soldier[5];//in the order of iceman¡¢lion¡¢wolf¡¢ninja¡¢dragon
public:
    int arr[2][5] = { {0, 1, 2, 3, 4} ,{1, 4, 3, 0, 2} };
    //int arr[5] = {1, 4, 3, 0, 2};
    battlefield(int n) :HP{ n, n}, hour(0), minute(0), produce_end{ true,true }
    {
        soldier_total[0] = soldier_total[1] = 0;
        cur[0] = cur[1] = -1;
        strcpy(name[0], "red");
        strcpy(name[1], "blue");
        memset(soldier, 0, sizeof(soldier));
        head = new csoldier** [city_number + 2];
        for (int i = 0; i < city_number + 2; ++i)
        {
            head[i] = new csoldier*[4];
            //memset(head[i], NULL, sizeof(csoldier*) * 4);
            memset(head[i], 0, sizeof(csoldier*) * 4);
        }
    }
    //輸出當前時間
    void out_time()
    {
        cout << setfill('0') << setw(3) << hour << ':' << setfill('0') << setw(2) << minute;
        return;
    }
 
    //base produce soldiers. if base produce soldier sucessfully, return true;if else return false;
    bool produce(int color)
    {
        if(produce_end[color] == false)
            return false;
        cur[color] = (cur[color] + 1) % 5;
        int t = arr[color][cur[color]];
        if(HP[color] >= soldier_HP[t])
        {
            HP[color] -= soldier_HP[t];
            soldier[t]++;
            soldier_total[color]++;
            out_time();
            cout << ' ' << name[color] << ' ' << soldier_name[t] << ' ' << soldier_total[color] << " born"<< endl;
            int pos = ((color == 0) ? 0 : city_number + 1);
            switch(t)
            {
                case 0: head[pos][color] = new iceman(soldier_total[color], color);break;
                case 1: head[pos][color] = new lion(soldier_total[color], color, HP[color]);break;
                case 2: head[pos][color] = new wolf(soldier_total[color], color);break;
                case 3: head[pos][color] = new ninja(soldier_total[color], color);break;
                case 4: head[pos][color] = new dragon(soldier_total[color], color);break;
            }
            return true;
        }
        else
        {
            produce_end[color] = false;
            return false;
        }
    }
    //renew location
    void clear()
    {
        for (int i = 0; i <= city_number + 1; ++i)
        {
            head[i][0] = head[i][2];
            head[i][1] = head[i][3];
            head[i][2] = head[i][3] = NULL;
        }
        return;
    }
 
    //soldiers start moving
    bool march()
    {
        bool flag = true;
 
        if (head[1][1] != NULL)
        {
            if (typeid(*head[1][1]) == typeid(iceman))
                head[1][1]->HP -= head[1][1]->HP / 10;
            out_time();
            cout << " blue "; head[1][1]->out_name();
            printf(" reached red headquarter with %d elements and force %d\n", head[1][1]->HP, head[1][1]->force);
            head[0][3] = head[1][1];
            out_time();
            cout << " red headquarter was taken" << endl;
            flag = false;
        }
        for (int i = 1; i <= city_number; ++i)
        {
            if (head[i - 1][0] != NULL)
            {
                if (typeid(*head[i - 1][0]) == typeid(iceman))
                    head[i - 1][0]->HP -= head[i - 1][0]->HP / 10;
                out_time();
                cout << " red "; head[i - 1][0]->out_name();
                printf(" marched to city %d with %d elements and force %d\n",i, head[i-1][0]->HP, head[i-1][0]->force);
                head[i][2] = head[i - 1][0];
            }
            if (head[i + 1][1] != NULL)
            {
                if (typeid(*head[i + 1][1]) == typeid(iceman))
                    head[i + 1][1]->HP -= head[i + 1][1]->HP / 10;
                out_time();
                cout << " blue "; head[i + 1][1]->out_name();
                printf(" marched to city %d with %d elements and force %d\n", i, head[i + 1][1]->HP, head[i + 1][1]->force);
                head[i][3] = head[i + 1][1];
            }
        }
        if (head[city_number][0] != NULL)
        {
            if (typeid(*head[city_number][0]) == typeid(iceman))
                head[city_number][0]->HP -= head[city_number][0]->HP / 10;
            out_time();
            cout << " red "; head[city_number][0]->out_name();
            printf(" reached blue headquarter with %d elements and force %d\n", head[city_number][0]->HP, head[city_number][0]->force);
            head[city_number + 1][2] = head[city_number][0];
            out_time();
            cout << " blue headquarter was taken" << endl;
            flag = false;
        }
        clear();
        return flag;
    }
 
    //judge whether lion run away
    void run_away()
    {
        for (int i = 0; i <= city_number + 1; ++i)
        {
            for (int t = 0; t < 2; ++t)
            {
                if (head[i][t] != NULL && typeid(*head[i][t]) == typeid(lion))
                {
                    auto p = (lion *)head[i][t];
                    if (p->loyalty <= 0)
                    {
                        out_time();
                        cout << ' ' << name[t];
                        cout << " lion " << head[i][t]->id << " ran away" << endl;
                        delete head[i][t];
                        head[i][t] = NULL;
                        continue;
                    }
                    p->loyalty -= lion::K;
                }
            }
 
        }
        return;
    }
 
    //winner snatch loser's weapon
    void snatch_weapon(csoldier *p, csoldier *q)
    {
        for (int i = 0; i < 4; ++i)
        {
            while (q->weapon[i] > 0 && p->weapen_amount < 10)
            {
                p->weapon[i]++;
                q->weapon[i]--;
                p->weapen_amount++;
            }
        }
        return;
    }
    void out_weapen(int t)
    {
        switch(t)
        {
            case 0: cout << weapon_name[0];break;
            case 1: cout << weapon_name[1];break;
            case 2: cout << weapon_name[2];break;
            case 3: cout << weapon_name[2];break;
        }
        return;
    }
    //wolf snatch enemy's weapon
    void w_snatch_weapon(csoldier *p, csoldier *q)
    {
        //bool flag = true;
 
        int t = 0, s = 0;
        while (q->weapon[t] == 0)++t;
        if (10 - p->weapen_amount <= q->weapon[t])
        {
            p->weapon[t] += 10 - p->weapen_amount;
            s += 10 - p->weapen_amount;
            p->weapen_amount = 10;
            q->weapen_amount -= s;
            q->weapon[t] -= s;
            return;
        }
        else
        {
            p->weapon[t] += q->weapon[t];
            s += q->weapon[t];
            p->weapen_amount += q->weapon[t];
            q->weapon[t] -= s;
            q->weapen_amount -= s;
            if (t == 2 && q->weapon[3] > 0)
            {
                t = 3;
                if (10 - p->weapen_amount <= q->weapon[t])
                {
                    p->weapon[t] += 10 - p->weapen_amount;
                    s += 10 - p->weapen_amount;
                    p->weapon[t] -= 10 - p->weapen_amount;
                    p->weapen_amount -= 10 - p->weapen_amount;
                    p->weapen_amount = 10;
                }
                else
                {
                    p->weapon[t] += q->weapon[t];
                    s += q->weapon[t];
                    q->weapen_amount -= q->weapon[t];
                    p->weapen_amount += q->weapon[t];
                    q->weapon[t] = 0;
                }
            }
            cout << s << ' ';
            out_weapen(t);
            return;
        }
    }
 
    //wolf snatch enemy's weapon
    void snatch()
    {
        for (int i = 1; i <= city_number; ++i)
        {
            csoldier *p[2] = { head[i][0], head[i][1] };
            if (p[0] != NULL && p[1] != NULL)
            {
 
                if (typeid(*p[0]) != typeid(wolf) && typeid(*p[1]) != typeid(wolf))
                    continue;
                else if (typeid(*p[0]) != typeid(wolf))
                {
                    if(p[0]->weapen_amount == 0 || p[1]->weapen_amount == 10)
                        continue;
                    out_time(); cout << " blue ";p[1]->out_name();
                    cout << " took ";
                    w_snatch_weapon(p[1], p[0]);
                    cout << " from red ";
                    p[0]->out_name();cout << " in city " << i << endl;
                }
                else if (typeid(*p[1]) != typeid(wolf))
                {
                    if(p[1]->weapen_amount == 0 || p[0]->weapen_amount == 10)
                        continue;
                    out_time(); cout << " red ";p[0]->out_name();
                    cout << " took ";
                    w_snatch_weapon(p[0], p[1]);
                    cout << " from blue ";
                    p[1]->out_name();cout << " in city " << i << endl;
                }
                else
                    continue;
 
            }
        }
    }
 
    //fight
    void fight()
    {
        for (int i = 1; i <= city_number; ++i)
        {
            if (head[i][0] == NULL || head[i][1] == NULL)
                continue;
            int r = i % 2, L = r ^ 1, n[2] = {1, 1}, w, flag = 5, check[4] = {0}, cnt = 0;
            while (true)
            {
                //判斷是否局勢改變,若不改變則為平局
                r = r ^ 1;
                L = L ^ 1;
                if (cnt == 0)
                {
                    if (check[0] == head[i][0]->HP && check[1] == head[i][1]->HP && check[2] == head[i][0]->weapen_amount && check[3] == head[i][1]->weapen_amount)
                    {
                        flag = 0;//all alive
                        break;
                    }
                    check[0] = head[i][0]->HP;
                    check[1] = head[i][1]->HP;
                    check[2] = head[i][0]->weapen_amount;
                    check[3] = head[i][1]->weapen_amount;
                    cnt = 10;
                }
                cnt--;
 
                if (head[i][L]->weapen_amount == 0 && head[i][r]->weapen_amount == 0)
                {
                    flag = 0;//alive
                    break;
                }
                if(head[i][r]->weapen_amount == 0)
                    continue;
                w = head[i][r]->getweapon(n[r]);
//                if(head[i][1]->id == 10)
//                cout << r << ' ' << "use weapen " << w << " in city " << i <<n[r] << endl;
                int h;
                switch (w)
                {
                case 0:
                    head[i][L]->HP -= head[i][r]->force / 5; break;
                case 1:
                    h = head[i][r]->force * 2 / 5;
                    head[i][L]->HP -= h;
                    if(typeid(*head[i][r]) != typeid(ninja))
                        head[i][r]->HP -= h / 2;
                    break;
                case 2:
                    head[i][L]->HP -= head[i][r]->force * 3 / 10; break;
                default:
                    break;
                }
                if (head[i][L]->HP <= 0 && head[i][r]->HP <= 0)
                {
                    flag = 3;//all died
                    break;
                }
                else if (head[i][L]->HP <= 0)
                {
                    if (L == 0)
                    {
                        flag = 2; //blue win
                        break;
                    }
                    else
                    {
                        flag = 1; //red win
                        break;
                    }
                }
                else if (head[i][r]->HP <= 0)
                {
                    if (r == 0)
                    {
                        flag = 2; //blue win
                        break;
                    }
                    else
                    {
                        flag = 1; //red win
                        break;
                    }
                }
            }
            out_time();
            switch (flag)
            {
            case 0:
                cout << " both red ";
                head[i][0]->out_name();
                cout << " and blue ";
                head[i][1]->out_name();
                cout << " were alive in city " << i << endl;
                break;
            case 3:
                cout << " both red ";
                head[i][0]->out_name();
                cout << " and blue ";
                head[i][1]->out_name();
                cout << " died in city " << i << endl;
                delete head[i][0];
                delete head[i][1];
                head[i][0] = NULL;
                head[i][1] = NULL;
                break;
            case 1:
                cout << " red ";
                head[i][0]->out_name();
                cout << " killed blue ";
                head[i][1]->out_name();
                printf(" in city %d remaining %d elements\n", i, head[i][0]->HP);
                snatch_weapon(head[i][0], head[i][1]);
                delete head[i][1];
                head[i][1] = NULL;
                break;
            case 2:
                cout << " blue ";
                head[i][1]->out_name();
                cout << " killed red ";
                head[i][0]->out_name();
                printf(" in city %d remaining %d elements\n", i, head[i][1]->HP);
                snatch_weapon(head[i][1], head[i][0]);
                delete head[i][0];
                head[i][0] = NULL;
                break;
            default:
                break;
            }
            for (int t = 0; t < 2; ++t)
            {
                if (head[i][t] != NULL && typeid(*head[i][t]) == typeid(dragon))
                {
                    out_time(); cout << ' ' << name[t] << ' ';
                    head[i][t]->out_name();
                    cout << " yelled in city " << i << endl;
                }
            }
 
        }
 
    }
 
    //base report condition
    void base_report()
    {
        out_time();
        printf(" %d elements in red headquarter\n", HP[0]);
        out_time();
        printf(" %d elements in blue headquarter\n", HP[1]);
        return;
    }
 
    //soldier report
    void soldier_report()
    {
        for (int i = 0; i < city_number + 1; ++i)
        {
            for(int t = 0; t < 2; ++t)
                if (head[i][t] != NULL)
                {
                    out_time();
                    cout << ' ' << name[t] << ' ';
                    head[i][t]->out_name();
                    cout << " has " << head[i][t]->weapon[0] << " sword " << head[i][t]->weapon[1] << " bomb "
                        << head[i][t]->weapon[2] + head[i][t]->weapon[3] << " arrow and " << head[i][t]->HP << " elements" << endl;
                }
        }
        return;
    }
 
    //check whether time is legal
    bool check_time()
    {
        if (hour * 60 + minute > time_limited)
            return false;
        else
            return true;
    }
 
    bool run()
    {
        minute = 0;
        if (!check_time()) return false;
 
        produce(0);
        produce(1);
 
        minute = 5;
        if (!check_time()) return false;
 
        run_away();
 
        minute = 10;
        if (!check_time()) return false;
 
        if(!march())
            return false;
 
        minute = 35;
        if (!check_time()) return false;
 
        snatch();
 
        minute = 40;
        if (!check_time()) return false;
 
        fight();
 
        minute = 50;
        if (!check_time()) return false;
        base_report();
 
        minute = 55;
        if (!check_time()) return false;
        soldier_report();
 
        hour++;
        return true;
    }
};
int main()
{
    int n, hp, cnt = 0;
    cin >> n;
    while(n--)
    {
        cout << "Case " << ++cnt <<':'<< endl;
                cin >> hp >> city_number >> lion::K >> time_limited;
                battlefield Battle(hp);
                cin >> soldier_HP[4] >> soldier_HP[3] >> soldier_HP[0] >> soldier_HP[1] >> soldier_HP[2];
        cin >> soldier_force[4] >> soldier_force[3] >> soldier_force[0] >> soldier_force[1] >> soldier_force[2];
        while (Battle.run());
 
    }
    return 0;
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM