狗狗40题搞完纪念 » 1019

1019
1019.cpp


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define P(p, a, b) ((p * a + (100 - p) * b) / 100.0)
#define LP_INIT_HP 999
#define LP_LEVEL 50
#define LP_GENDER 0
#define RECOVER_HP 200
// #define X_CHOP_ACC 0.3
#define X_CHOP_ACC 30
#define X_CHOP_DAM 300

/*
   inline double max(double a, double b) {
   printf("\t%lf\n", b);
   if (a > b) return a; else return b;
   }
   */
struct LegendaryPokemon {
	int level, gender, maxhp;
	int run[5], p[5];
	int n, c[4][4];

	struct StatusA {	// sizeof(A) = 8
		char b[5];		// the number of corresponding balls you have: 1~5
		int hp: 12;		// initial(and maximal) HP value: -???~999+200
		int nhp: 5;		// the number of Hyper Potions: 0~10
	};

	struct StatusB {	// sizeof(B) = 8
		int hp: 12;		// initial(and maximal) HP value: -???~999
		int nhp: 5;		// the number of Hyper Potions: 0~10
		int confuse: 8;	// confusion: 0~100
		int status: 2;	// sleepy(0), confused(1)
		int sr: 3;		// These will be effective within 3 rs
		int poison: 11;	// poison value: 0~999
		int pr: 3;		// The effect lasts for 3 rs
	};

	int p1, p2, bb[5];
	/*
		void dump(int r, StatusA a, StatusB b) const {
		printf("Round %d:\n", r);

		printf("%d(%d): {", a.hp, a.nhp);
		for (int i = 0; i < 5; ++i) {
		printf("%d, ", (int)a.b[i]);
		}
		puts("}");

		printf("%d(%d):", b.hp, b.nhp);
		printf(" pr=%d(%d) sr=%d(%d,%d)\n", b.pr, b.poison, b.sr, b.status, b.confuse);
		}
		*/
	double gao() {
		StatusA a;
		StatusB b;

		for (int i = 0; i < 5; ++i) {
			a.b[i] = bb[i];
		}
		a.hp = maxhp;
		a.nhp = p1;

		memset(&b, 0, sizeof(StatusB));
		b.hp = LP_INIT_HP;
		b.nhp = p2;

		p[0] = 5;
		p[1] = 10;
		p[2] = 15;
		p[3] = level > LP_LEVEL ? 18 : p[1];
		p[4] = gender != LP_GENDER ? 20 : 0;

		// dump(-1, a, b);

		return gao1(0, a, b);
	}

	double gao1(int r, StatusA a, StatusB b) const {
		// dump(r, a, b);
		if (a.hp <= 0 || b.hp <= 0) {
			return 0;
		}
		if (a.b[0] == 0 && a.b[1] == 0 && a.b[2] == 0 && a.b[3] == 0 && a.b[4] == 0) {
			return 0;
		}

		double ret = 0;

		// A move
		double tmp = gao2(r, a, b);
		for (int i = 0; i < n; ++i) {
			// printf("> move %d\n", i);
			StatusB b2 = b;
			int pp = c[i][2];
			switch (c[i][0]) {
			case 1:
				b2.hp -= c[i][1];
				break;
			case 2:
				if (b2.sr == 0) {
					b2.sr = 3;
					if (c[i][1] == 0) {
						b2.status = 0;
					} else {
						b2.status = 1;
						b2.confuse = c[i][1];
					}
				}
				break;
			case 3:
				b2.hp -= c[i][1];
				if (b2.pr == 0) {
					b2.pr = 3;
					b2.poison = c[i][2];
				}
				pp = c[i][3];
				break;
			}
			ret = max(ret, P(pp, gao2(r, a, b2), tmp));
		}

		// A BALL
		for (int i = 0; i < 5; ++i) {
			// printf("> ball %d\n", i);
			if (a.b[i] > 0) {
				int pp = p[i];
				if (b.hp <= 50) {	// CriticalLifeBonus
					pp += 10;
				} else if (b.hp <= 100) {
					pp += 5;
				}
				if (b.pr > 0) {	// PoisonedBonus
					pp += 10;
				}
				if (b.sr > 0) {	// StatusBonus
					pp += 5;
				}
				--a.b[i];
				ret = max(ret, P(pp, 1, gao2(r, a, b)));
				++a.b[i];
			}
		}

		// heal
		if (a.nhp > 0) {
			// HP values can never be greater than their maximal values (@fix{1})
			a.hp = min(maxhp, a.hp + RECOVER_HP);
			--a.nhp;
			ret = max(ret, gao2(r, a, b));
		}

		return max(ret, tmp);	// do_nothing (@fix{3})
	}

	double gao2(int r, StatusA a, StatusB b) const {
		if (a.hp <= 0 || b.hp <= 0) {
			return 0;
		}

		// dump(r, a, b);
		// 1. In the ith r, he may decide to run away. ...
		if (run[r] >= 100) {
			return 0;
		}

		// 2. If he decided to continue the battle, he check if his HP. ...
		if (b.hp <= 150 && b.nhp > 0) {
			b.hp += RECOVER_HP;	//
			--b.nhp;
			if (b.pr > 0) {	//
				--b.pr;
				if ((b.hp -= b.poison) <= 0) {
					return 0;
				}
			}
			if (b.sr > 0) {	//
				--b.sr;
			}
			return (1 - run[r] / 100.0) * gao1(r + 1, a, b);
		}

		if (b.pr > 0) {
			--b.pr;
			if ((b.hp -= b.poison) <= 0) {
				return 0;
			}
		}

		if (b.sr > 0) {
			--b.sr;
			double tmp = gao1(r + 1, a, b);
			if (b.status == 0) {	// WA.. 手抖
				return (1 - run[r] / 100.0) * tmp;
			} else {
				StatusA a2 = a;
				a2.hp -= X_CHOP_DAM;
				StatusB b2 = b;
				b2.hp -= X_CHOP_DAM;
				return (1 - run[r] / 100.0) * P(b.confuse,
					P(X_CHOP_ACC, gao1(r + 1, a, b2), tmp),
					P(X_CHOP_ACC, gao1(r + 1, a2, b), tmp));
			}
		} else {
			StatusA a2 = a;
			a2.hp -= X_CHOP_DAM;
			return (1 - run[r] / 100.0) * P(X_CHOP_ACC, gao1(r + 1, a2, b), gao1(r + 1, a, b));
		}
	}
};

int main() {
	LegendaryPokemon lp;

	while (scanf("%d%d%d", &lp.level, &lp.gender, &lp.maxhp) != EOF && lp.maxhp > 0) {
		for (int i = 0; i < 5; ++i) {
			scanf("%d", &lp.run[i]);
		}
		scanf("%d%d", &lp.p1, &lp.p2);
		for (int i = 0; i < 5; ++i) {
			scanf("%d", &lp.bb[i]);
		}
		scanf("%d", &lp.n);
		for (int i = 0; i < lp.n; ++i) {
			scanf("%d%d%d", &lp.c[i][0], &lp.c[i][1], &lp.c[i][2]);
			if (lp.c[i][0] == 3) {
				scanf("%d", &lp.c[i][3]);
			}
		}
		printf("%.4lf\n", lp.gao());
	}

	return 0;
}

//Run ID  	Submit Time  	Judge Status  	Problem ID  	Language  	Run Time(ms)  	Run Memory(KB)  	User Name  	Admin
//412 	2010-07-07 16:03:51 	Accepted 	1019 	C++ 	310 	180 	anotherpeg 	Source

/*
0 0 800
10 20 30 100 100
1
4
1 1 0 2 0
4
2 21 87
2 0 57
2 33 93
2 2 71
0 0 0
0.2572	<- xgy
0.2584	<- gougou
0.2581	<- watashi
*/
One Response to “1019”
  1. Bobgy says:

    最后注释里的数据我跑的和你一样。

  2.  
Leave a Reply