程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 11589 - Save the President(暴力+技巧枚舉)

11589 - Save the President(暴力+技巧枚舉)

編輯:C++入門知識

鏈接:11589 - Save the President

題意:有n個爆炸區域,每個區域有一個爆炸時間,現在要保護總統,要保證總統的生存空間為x, y, z;並且不被炸到,問有多少個不同時間空間的位置。 思路:算上時間,算是一個四維坐標系,問題轉化為四維坐標系上有一些點,你要找出前三維大小為(x,y,z)的所有位置。 且這個大小內沒有點。 這題我直接暴力就過了。。而且時間很快,8層for居然不超時。 然後看了網上一個大神的代碼,簡直屌,大概是運用了前綴求區間和,然後去判斷一個區間的時候就減掉即可。不過這題是四維的,常規方法解決起來容易寫亂,學習了大神的方法。鏈接:https://code.google.com/r/469841185-13a/source/browse/TrainingGuide/exercises/ch1/Efficient/uva11589.cpp?spec=svne76e7c8fa296c14c703a746d1e7dbab8aa115212&r=e76e7c8fa296c14c703a746d1e7dbab8aa115212#37 代碼: 暴力過的:
#include 
#include 

const int N = 2505;
int n, q, h1, m1, h2, m2, time1, time2, vis[20][20][20][105], tim;
struct Point {
	int x, y, z;
	Point() {}
	void scan() {
		scanf("%d%d%d", &x, &y, &z);
	}
} p, s, e, v;

bool judge(int x, int y, int z, int ti) {
	int i, j, k, l;
	for (i = x; i < x + v.x; i++) {
		for (j = y; j < y + v.y; j++) {
			for (k = z; k < z + v.z; k++) {
				for (l = ti; l < ti + tim; l++) {
					if (vis[i][j][k][l]) return false;
				}
			}
		}
	}
	return true;
}

int solve() {
	int ans = 0, i, j, k, t;
	for (i = 0; i <= p.x - v.x; i++) {
		for (j = 0; j <= p.y - v.y; j++) {
			for (k = 0; k <= p.z - v.z; k++) {
				for (t = 0; t <= 96 - tim; t++) {
					if (judge(i, j, k, t)) {
						ans++;
					}
				}
			}
		}
	}
	return ans;
}

int main() {
	int cas = 0;
	while (~scanf("%d%d%d%d%d", &n, &p.x, &p.y, &p.z, &q) && n) {
		memset(vis, 0, sizeof(vis));
		for (int i = 1; i <= n; i++) {
			s.scan(); e.scan();
			scanf("%d:%d%d:%d", &h1, &m1, &h2, &m2);
			time1 = h1 * 4 + m1 / 15;
			time2 = h2 * 4 + m2 / 15;
			for (int x = s.x; x < e.x; x++) {
				for (int y = s.y; y < e.y; y++) {
					for (int z = s.z; z < e.z; z++) {
						for (int t = time1; t < time2; t++) {
							vis[x][y][z][t] = 1;
						}
					}
				}
			}
		}
		printf("3D World %d:\n", ++cas);
		while (q--) {
			v.scan();
			scanf("%d:%d", &h1, &m1);
			tim = h1 * 4 + m1 / 15;
			int ans = solve();
			if (ans)
				printf("%d safe place(s) found\n", ans);
			else
				printf("No safe place(s) found\n");
		}
	}
	return 0;
}

借鑒大神的方法:
#include 
#include 

const int N = 20;
const int M = 105;

int sum[N][N][N][M], n, dx, dy, dz, q, b0, b1, b2, b3;

void tra(int bit) {
	b0 = bit&1; b1 = (bit>>1)&1; b2 = (bit>>2)&1; b3 = (bit>>3);
}

int coeff() {
	return (b0 + b1 + b2 + b3) % 2 == 1 ? 1 : -1;
}

int solve(int x, int y, int z, int t) {
	int ans = 0;
	for (int i = 1; i <= dx - x + 1; i++)
		for (int j = 1; j <= dy - y + 1; j++)
			for (int k = 1; k <= dz - z + 1; k++)
				for (int l = 1; l <= 96 - t + 1; l++) {
					int s = 0;
					for (int bit = 0; bit < 16; bit++) {
						tra(bit);
						s += sum[i - 1 + b0 * x][j - 1 + b1 * y][k - 1 + b2 * z][l - 1 + b3 * t] * coeff();
					}
					if (!s)
						ans++;
				}
	return ans;
}

int main() {
	int cas = 0;
	while (~scanf("%d%d%d%d%d", &n, &dx, &dy, &dz, &q) && n) {
		memset(sum, 0, sizeof(sum));
		printf("3D World %d:\n", ++cas);
		while (n--) {
			int x1, y1, z1, x2, y2, z2, h1, m1, h2, m2;
			scanf("%d%d%d%d%d%d%d:%d%d:%d", &x1, &y1, &z1, &x2, &y2, &z2, &h1, &m1, &h2, &m2);
			int t1 = h1 * 4 + m1 / 15, t2 = h2 * 4 + m2 / 15;
			for (int i = x1 + 1; i <= x2; i++)
				for (int j = y1 + 1; j <= y2; j++)
					for (int k = z1 + 1; k <= z2; k++)
						for (int l = t1 + 1; l <= t2; l++)
							sum[i][j][k][l] = 1;
		}
		for (int i = 1; i <= dx; i++)
			for (int j = 1; j <= dy; j++)
				for (int k = 1; k <= dz; k++)
					for (int l = 1; l <= 96; l++)
						for (int bit = 1; bit < 16; bit++) {
							tra(bit);
							sum[i][j][k][l] += sum[i - b0][j - b1][k - b2][l - b3] * coeff();
						}
						while (q--) {
							int x, y, z, h, m;
							scanf("%d%d%d%d:%d", &x, &y, &z, &h, &m);
							int t = h * 4 + m / 15;
							int ans = solve(x, y, z, t);
							if (ans) printf("%d safe place(s) found\n", ans);
							else printf("No safe place(s) found\n");
						}
	}
	return 0;
}



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved