Paiza工程师死绝的世界 有名なプールサイド [MISSION LEVEL: A]高分题解

**

原题 https://paiza.jp/botchi/challenges/botchi_a_1001

**
咳咳,代码有点长,我就不说明了。。

#include <bits/stdc++.h>
using namespace std;

int H, W, N;
int vis[4][2] = { -1,0,1,0,0,-1,0,1 };

struct place
{
	vector<vector<int>> ans;
	vector<vector<int>> dp;
	int score;
};

struct node
{
	int h, w, r, c, dir, id, a, b;
	bool use;
	bool operator < (const node& temp) const
	{
		if (h * w != temp.h * temp.w) return h * w > temp.h* temp.w;
		return abs(h - w) < abs(temp.h - temp.w);
	}
};

vector<node> v1;
vector<place> v2;
vector<vector<int>> tmp;

void init()
{
	cin >> H >> W >> N;
	v1.resize(N);
	for (int i = 0; i < N; i++)
	{
		cin >> v1[i].h >> v1[i].w >> v1[i].r >> v1[i].c;
		if (v1[i].r == 1) v1[i].dir = 1;
		else if (v1[i].r == v1[i].h) v1[i].dir = 2;
		else if (v1[i].c == 1) v1[i].dir = 3;
		else v1[i].dir = 4;
		v1[i].id = i + 1;
	}
}

void draw(int a, int b, int n, int id) 
{
	for (int i = a; i < a + v1[n].h; i++) 
	{
		for (int j = b; j < b + v1[n].w; j++) 
		{
			v2.back().ans[i][j] = id;
		}
	}
}

void dfs(int a, int b) 
{
	tmp[a][b] = 1;
	for (int i = 0; i < 4; i++) 
	{
		int na = a + vis[i][0];
		int nb = b + vis[i][1];
		if (na >= 0 && nb >= 0 && na < H && nb < W && !tmp[na][nb]) 
		{
			dfs(na, nb);
		}
	}
}

bool judge(int a,int b,int n)
{
	if (b + v1[n].w > W || a + v1[n].h > H) return false;
	for (int i = a; i < a + v1[n].h; i++) 
	{
		for (int j = b; j < b + v1[n].w; j++) 
		{
			if (v2.back().ans[i][j] || v2.back().dp[i][j]) return false;
		}
	}
	int aa = a + v1[n].r - 1, bb = b + v1[n].c - 1;
	draw(a, b, n, v1[n].id);
	tmp = v2.back().ans;
	dfs(aa, bb);
	for (auto i : tmp) 
	{
		for (auto j : i) 
		{
			if (!j) 
			{
				draw(a, b, n, 0);
				return false;
			}
		}
	}
	v2.back().dp[aa + vis[v1[n].dir - 1][0]][bb + vis[v1[n].dir - 1][1]] = 1;
	v1[n].a = a, v1[n].b = b, v1[n].use = true;
	return true;
}

void check() 
{
	int c1 = 0;
	for (auto i : v2.back().ans) 
	{
		for (auto j : i) 
		{
			if (j) c1++;
		}
	}
	v2.back().score = c1;
}

void solvef()
{
	for (int k = 0; k < N; k++)
	{
		if (v1[k].use) continue;
		for (int i = 0; i < H; i++)
		{
			for (int j = 0; j < W; j++)
			{
				if (judge(i, j, k)) goto next;
			}
		}
	next:;
	}
}

void movespace() 
{
	for (int i = 0; i < N; i++)
	{
		if (!v1[i].use) continue;
		int a = v1[i].a, b = v1[i].b;
		int aa = a + v1[i].r - 1, bb = b + v1[i].c - 1;
		if (a - 1 >= 0 && !v2.back().ans[a - 1][b]) 
		{
			v2.back().dp[aa + vis[v1[i].dir - 1][0]][bb + vis[v1[i].dir - 1][1]] = 0;
			draw(a, b, i, 0);
			if (judge(a - 1, b, i))
			{
				movespace();
				return;
			}
			else
			{
				draw(a, b, i, v1[i].id);
				v2.back().dp[aa + vis[v1[i].dir - 1][0]][bb + vis[v1[i].dir - 1][1]] = 1;
			}
		}
		if (b - 1 >= 0 && !v2.back().ans[a][b - 1]) 
		{
			v2.back().dp[aa + vis[v1[i].dir - 1][0]][bb + vis[v1[i].dir - 1][1]] = 0;
			draw(a, b, i, 0);
			if (judge(a, b - 1, i)) 
			{
				movespace();
				return;
			}
			else
			{
				draw(a, b, i, v1[i].id);
				v2.back().dp[aa + vis[v1[i].dir - 1][0]][bb + vis[v1[i].dir - 1][1]] = 1;
			}
		}
	}
}

void initsolve() 
{
	struct place plc;
	plc.ans.assign(H, vector<int>(W, 0));
	plc.dp.assign(H, vector<int>(W, 0));
	v2.emplace_back(plc);
	for (auto& i : v1) 
	{
		i.a = 0, i.b = 0, i.use = false;
	}
}

void solve()
{
	initsolve();
	for (int k = 0; k < N; k++)
	{
		switch (v1[k].dir)
		{
		case 1:
			for (int i = H - 1; i >= 0; i--) 
			{
				for (int j = W - 1; j >= 0; j--) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 2:
			for (int i = 0; i < H; i++)
			{
				for (int j = 0; j < W; j++)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 3:
			for (int j = W - 1; j >= 0; j--)
			{
				for (int i = H - 1; i >= 0; i--)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 4:
			for (int j = 0; j < W; j++)
			{
				for (int i = 0; i < H; i++)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		}
	next:;
	}
	movespace();
	solvef();
	check();
}

void solve1()
{
	initsolve();
	for (int k = 0; k < N; k++)
	{
		switch (v1[k].dir)
		{
		case 1:
			for (int i = H - 1; i >= 0; i--)
			{
				for (int j = 0; j < W; j++)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 2:
			for (int i = 0; i < H; i++)
			{
				for (int j = W - 1; j >= 0; j--) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 3:
			for (int j = W - 1; j >= 0; j--)
			{
				for (int i = 0; i < H; i++) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 4:
			for (int j = 0; j < W; j++)
			{
				for (int i = H - 1; i >= 0; i--) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		}
	next:;
	}
	movespace();
	solvef();
	check();
}

void solve2()
{
	initsolve();
	for (int k = 0; k < N; k++)
	{
		switch (v1[k].dir)
		{
		case 1:
			for (int i = H - 1; i >= 0; i--)
			{
				for (int j = W - 1; j >= 0; j--) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 2:
			for (int i = 0; i < H; i++)
			{
				for (int j = 0; j < W; j++)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 3:
			for (int j = W - 1; j >= 0; j--)
			{
				for (int i = 0; i < H; i++)
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		case 4:
			for (int j = 0; j < W; j++)
			{
				for (int i = 0; i < H; i++) 
				{
					if (judge(i, j, k)) goto next;
				}
			}
			break;
		}
	next:;
	}
	movespace();
	solvef();
	check();
}

void cal() 
{
	int c1 = 0, index = 0, len = v2.size();
	for (int i = 0; i < len; i++) 
	{
		//cout << v2[i].score << endl;
		if (v2[i].score > c1) 
		{
			c1 = v2[i].score;
			index = i;
		}
	}
	for (auto i : v2[index].ans) 
	{
		for (int j = 0; j < W - 1; j++) 
		{
			cout << i[j] << " ";
		}
		cout << i[W - 1] << endl;
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	init();
	sort(v1.begin(), v1.end());
	solve();
	solve1();
	solve2();
	cal();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值