Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 122 | Accepted: 54 |
Description
Input
Output
Sample Input
1 2 1 3 1 1 1 0 100 1 99 2 50 100 200 300
Sample Output
Mission #1: 1 bomber(s) exploded
Source
#include <iostream> #include <algorithm> #define MAX_N 305 using namespace std; //记录bomber的有关信息 struct bomber { int x, y; int v; }bombers[MAX_N]; //有效bomber对于在bombers中的下标以及有效bomber的数量 int validIndex[MAX_N]; int validNum; //记录有所民航飞机的信息 struct plane { int x, y; }planes[MAX_N]; //记录所有导弹的信息 struct missle { int x, rnum; int rel[MAX_N]; }missles[MAX_N]; int bn, pn, mn, sb, sp, sm, caseN; //对导弹进行排序的比较函数,按照X轴递增排序 bool compare(const bomber &b1, const bomber &b2) { return b1.x <= b2.x; } //判断导弹m能否击中轰炸机b bool canHit(int b, int m) { if(missles[m].x <= bombers[b].x) return false; return (missles[m].x - bombers[b].x) * sm >= bombers[b].y * sb; } //判断b1,b2是否是等价bomber bool theSameBomber(int b1, int b2) { if(bombers[b1].y >= bombers[b2].y) return false; return (bombers[b1].x - bombers[b2].x) * sm == (bombers[b2].y - bombers[b1].y) * sb; } //判断导弹m在击中轰炸机b之前是否会击中民航客机p bool theSameBP(const bomber &b, const plane &p, const missle &m) { if(!(m.x >= b.x && m.x >= p.x && p.y < b.y)) return false; if((m.x - b.x) * sm < b.y * sb) return false; if((m.x - p.x) * sm < p.y * sp) return false; //导弹发射前,bomber飞行的时间 double ft = double(m.x - b.x) / sb - double(b.y) / sm; //导弹发射时,bomber与导弹的x轴距离 double s1 = m.x - b.x - ft * sb; //导弹发射时,bomber与导弹的y轴距离 double s2 = b.y; //导弹发射时,plane与导弹的x轴距离 double s3 = m.x - p.x - ft * sp; //导弹发射时,plane与导弹的y轴距离 double s4 = p.y; //plane是否会阻拦导弹攻击bomber if((__int64)s1 * sp * s4 != (__int64)s2 * sb * s3) return false; return true; } //匈牙利算法的相关参数 int pre[MAX_N]; bool v[MAX_N]; //找增广路径 bool can(int node) { for(int i = 0; i < missles[node].rnum; i++) { int to = missles[node].rel[i]; if(v[to]) continue; v[to] = true; if(pre[to] == -1 || can(pre[to])) { pre[to] = node; return true; } } return false; } int main() { int c = 0, i, j, k; scanf("%d", &caseN); for(c = 1; c <= caseN; c++) { //输入与初始化 scanf("%d%d%d", &bn, &pn, &mn); scanf("%d%d%d", &sb, &sp, &sm); for(j = 0; j < bn; j++) { scanf("%d%d", &bombers[j].x, &bombers[j].y); bombers[j].v = -1; } for(j = 0; j < pn; j++) scanf("%d%d", &planes[j].x, &planes[j].y); for(j = 0; j < mn; j++) { scanf("%d", &missles[j].x); missles[j].rnum = 0; } sort(bombers, bombers + bn, compare); validNum = 0; //合并等价bomber for(i = bn - 1; i >= 0; i--) { if(bombers[i].v == -1) { validIndex[validNum++] = i; bombers[i].v = i; } else continue; for(j = i - 1; j >= 0; j--) { if(bombers[j].v != -1) continue; if(theSameBomber(i, j)) bombers[j].v = i; } } //建图 for(k = 0; k < mn; k++) { for(j = 0; j < validNum; j++) { bool can = true; int index = validIndex[j]; if(!canHit(index, k)) continue; for(i = 0; i < pn; i++) { if(theSameBP(bombers[index], planes[i], missles[k])) { can = false; break; } } if(can) missles[k].rel[missles[k].rnum++] = j; } } //匈牙利算法 int countv = 0; for(i = 0; i < validNum; i++) pre[i] = -1; for(i = 0; i < mn; i++) { memset(v, 0, sizeof(v)); if(can(i)) countv++; } printf("Mission #%d: %d bomber(s) exploded/n", c, countv); } return 0; }