题解 CF995A 【Tesla】

考虑把刚好在车位前面的车停进去,然后剩下的车统一轮换,能停的时候就停进去,不断重复这个过程。

因为中间的车道是 2×n 的格子,最坏情况一辆车要转一圈才能找到车位,找到车位后还要一次操作停进去,总共 k 辆车,最坏的操作次数为 k×(2×n+1)10100<20000,因此这种方法可行。

无解的话就判断没有车被轮换的时候是全都停到了车位里还是全都动不了即可。

//By: Luogu@rui_er(122461)
#include <bits/stdc++.h>
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
using namespace std;
typedef long long ll;
const int N = 205; 

int n, m, a[5][N];
tuple<int, int> s[N], t[N];
vector<tuple<int, int, int> > ans;
template<typename T> void chkmin(T &x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T &x, T y) {if(x < y) x = y;}
tuple<int, int> getNext(const tuple<int, int>& pos) {
	int x = get<0>(pos), y = get<1>(pos);
	if(x == 2) {
		if(y == n) return make_tuple(3, n);
		return make_tuple(2, y+1);
	}
	if(y == 1) return make_tuple(2, 1);
	return make_tuple(3, y-1);
}
bool isEmpty(const tuple<int, int>& pos) {
	return !a[get<0>(pos)][get<1>(pos)];
}
bool checkPark(const int& id) {
	if(abs(get<0>(s[id])-get<0>(t[id])) == 1 && get<1>(s[id]) == get<1>(t[id])) {
		ans.push_back(make_tuple(id, get<0>(t[id]), get<1>(t[id])));
		a[get<0>(s[id])][get<1>(s[id])] = a[get<0>(t[id])][get<1>(t[id])] = 0;
		return 1;
	}
	return 0;
}
bool rotateR() {
	bool ok = 0;
	rep(i, 2, 3) {
		rep(j, 1, n) {
			if(!a[i][j]) continue;
			tuple<int, int> nxt = getNext(make_tuple(i, j));
			if(checkPark(a[i][j])) ok = 1;
			else if(isEmpty(nxt)) {
				int id = a[i][j];
				ans.push_back(make_tuple(id, get<0>(nxt), get<1>(nxt)));
				a[i][j] = 0;
				a[get<0>(nxt)][get<1>(nxt)] = id;
				s[id] = nxt;
				ok = 1;
			}
		}
	}
	return ok;
}

int main() {
	scanf("%d%d", &n, &m);
	rep(i, 1, 4) rep(j, 1, n) {
		scanf("%d", &a[i][j]);
		if(a[i][j]) {
			if(i == 1 || i == 4) t[a[i][j]] = make_tuple(i, j);
			else s[a[i][j]] = make_tuple(i, j);
		}
	}
	while(rotateR())
		;
	bool tag = 1;
	rep(i, 1, 4) {
		rep(j, 1, n) if(a[i][j]) {tag = 0; break;}
		if(!tag) break;
	}
	if(!tag) puts("-1");
	else {
		int sz = ans.size();
		printf("%d\n", sz);
		for(auto p : ans) printf("%d %d %d\n", get<0>(p), get<1>(p), get<2>(p));
	}
	return 0;
}
posted @   rui_er  阅读(46)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示