逆向思考 C. Fence Painting

39 篇文章 0 订阅

Problem - 1481C - Codeforces

在这里插入图片描述

思路:逆序考虑,因为每一块木板都是被最后一次粉刷所决定的。

从后往前开始,对于 c i c_i ci来说,

  • 如果这个颜色还有没有涂的木板,那么涂到其中一个木板即可
  • 如果这个颜色下没有未涂的木板,找到一个已经土过的木板
  • 如果这个颜色没有被涂,且没有已经被涂的木板,那么涂到一个相同木板上
  • 如果这个颜色没有被涂,却没有已经被涂的木板,同时也没有相同木板,那么无解

最后再检验一下,是否可行即可。

代码如下:

void solve() {
	int n,m; cin>>n>>m;
	bool ok = true;
	int pos = -1;
	vector<int> a(n + 1), b(a), c(m + 1),ans(m + 1), e(n + 1, -1);
	/**
	 * ans存第j个人涂哪个木板
	 * e存第z个颜色的最远位置
	*/
	vector<vector<int>> g(n + 1);
	for(int i = 1 ; i <= n; ++i) cin>>a[i];
	for(int i = 1; i <= n; ++i) cin>>b[i];
	for(int i = 1; i <= m; ++i) cin>>c[i];
	for(int i = 1;  i <= n; ++i) {
		// 不相同表示,需要更改,先进行标记
		if(a[i] != b[i]) g[b[i]].push_back(i);
		e[b[i]] = i;
	}

	for(int i = m; i >= 1; --i) {
		// 现在木板中,没有将木板颜色更改为ci的需求
		if(g[c[i]].size() == 0) {
			// 如果是-1,表示没有已经被涂色的
			if(pos == -1) {
				// 如果这个ci颜色在木板中不存在,结束
				if(e[c[i]] == -1) {
					ok = false;
					break;
				}
				// 否则涂到相同木板上
				pos = e[c[i]];
			}
		} else {
			// 位置更新
			pos = g[c[i]].back();
			g[c[i]].pop_back();
			a[pos] = b[pos];
		}
		// 第i个人要涂的位置
		ans[i] = pos;
	}

	// 检查一下是否符合
	for(int i = 1; i <= n; ++i) ok &= a[i] == b[i];
	if(ok) {
		cout<<"YES\n";
		for(int i = 1; i <= m; ++i) cout<<ans[i]<<" \n"[i == m];
	} else cout<<"NO\n";
}

CF1481C Fence Painting - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

golemon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值