codeforces1428D Bouncing Boomerangs (Codeforces Raif Round 1 (Div. 1 + Div. 2))

题目链接:

https://codeforces.com/problemset/problem/1428/D

题目大意:

给定一个n*n的网格,现在从每一列的最下方向上仍一个回旋镖
网格上有一些障碍物,当回旋镖击打到障碍物时,其会按照
(上到左,左到下,下到右)顺时针方向更改飞行方向,直到出网格
现在我们设在第i列扔出去的飞镖击打到障碍物的个数为ai
给定 a1, a2, ... an 问是否能使用0 <= t <= 2*n 个障碍物使其得以满足
 

输入与输出:

输入:

第一行一个n代表网格大小,之后n个数代表ai(0 <= ai <= 3)

输出:

如果能满足a1到an则输出一个t代表障碍物数量
跟着t行代表每个障碍物坐标(行,列)
如果不能满足,则输出-1

思路:

因为飞镖顺时针改变方向,我们则应该从右到左来讨论
因为ai很小,我们可以分组讨论一下,
如果ai为0
则其实这一列我们可以直接忽略掉
如果ai为1
则这一列会占用一行未放置任何障碍物的行
如果ai为2
则这一列需要用一行已经放了一行障碍物的行
如果ai为3
则这一列需要一行空行,且需要某只放了一个障碍物的列

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e5 + 5;

int n, nums2, nums1, nums0, minNotUse;
int xx[maxn];
queue<pair<int, int>> que1, que2;
queue<pair<int, int>> resque;

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%d", &xx[i]);
	bool ff = 1;

	nums0 = n;
	minNotUse = 1;
	for (int ii = n; ii >= 1; ii--) {
		if (!xx[ii]) continue;
		else if (xx[ii] == 1) {
			if (!nums0) {
				ff = 0;
				break;
			}
			nums0--;
			nums1++;
			que1.push(make_pair(ii, minNotUse));
			resque.push(make_pair(ii, minNotUse));
			minNotUse++;
		}
		else if (xx[ii] == 2) {
			if (!nums1) {
				ff = 0;
				break;
			}
			nums1--;
			nums2++;
			int ii1 = que1.front().first;
			int jj1 = que1.front().second;
			que1.pop();
			que2.push(make_pair(ii, jj1));
			resque.push(make_pair(ii, jj1));
		}
		else {
			if (!nums0 || (!nums1 && !nums2)) {
				ff = 0;
				break;
			}
			nums0--;
			int ii1;
			int jj1;
			if (nums2) {
				ii1 = que2.front().first;
				jj1 = que2.front().second;
				que2.pop();
				nums2--;
			}
			else{
				ii1 = que1.front().first;
				jj1 = que1.front().second;
				que1.pop();
				nums1--;
			}
			nums2++;
			que2.push(make_pair(ii, minNotUse));
			resque.push(make_pair(ii, minNotUse));
			resque.push(make_pair(ii1, minNotUse));
			minNotUse++;
		}
	}
	if (!ff) printf("-1\n");
	else {
		printf("%d\n", resque.size());
		while (resque.size()) {
			printf("%d %d\n", n - resque.front().second + 1, resque.front().first);
			resque.pop();
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值