codeforces1428DBouncing Boomerangs(Codeforces Raif Round 1 (Div. 1 + Div. 2))

it2025-05-06  19

题目链接:

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)