The 2021 CCPC Guilin Onsite D. Assumption is All You Need(贪心)

Assumption is All You Need

https://codeforces.com/gym/103409/problem/D

①从左往右按下标遍历,若 a [ i ] = b [ i ] a[i]=b[i] a[i]=b[i] 则无需再调整,写几个样例会发现调整会不断破坏更前面已经匹配好的位置,所以已经匹配好的就不考虑再做操作了。

②若当前 a [ i ] < b [ i ] a[i]<b[i] a[i]<b[i] ,则直接没有答案,因为是操作逆序对,向后考虑操作只能换来更小值,不可能匹配上。

③若 a [ i ] > b [ i ] a[i]>b[i] a[i]>b[i] ,我们不能直接交换在 a a a 中等于 b [ i ] b[i] b[i] 的位置,因为我们在途中可以进行一些使得后续操作更优的交换。我们此时可以不断操作的也就是,某个 j j j 满足 a [ j ] < a [ i ] a[j]<a[i] a[j]<a[i] (因必须逆序)且 a [ j ] ≥ b [ i ] a[j]\geq b[i] a[j]b[i] (换了小于的就变回②了),那么我们只要遇到这样的位置就发生交换,因为这样可以尽可能使得比较大的元素在前面,尽可能拓展后续操作的可能性,直至交换完出现 a [ i ] = b [ i ] a[i]=b[i] a[i]=b[i] 的情况停止。

#include <bits/stdc++.h>

using namespace std;

const int N = 3000;

int n;
int a[N], b[N];
vector< pair<int, int> > ans;

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
	int T; scanf("%d", &T);
	while(T--) {
		ans.clear();
		scanf("%d", &n);
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &a[i]);
		}
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &b[i]);
		}
		bool ok = true;
		for (int i = 1; i <= n; ++i) {
			if (a[i] == b[i]) continue;
			if (a[i] < b[i]) {
				ok = false;
				break;
			}
			int j = i + 1;
			while(j <= n && a[i] != b[i]) {
				if (a[j] < a[i] && a[j] >= b[i]) {
					swap(a[i], a[j]);
					ans.push_back({i, j});
				}
				j++;
			}
			if (a[i] != b[i]) {
				ok = false;
				break;
			}
		}
		if (ok) {
			printf("%d\n", (int)ans.size());
			for (auto v : ans) {
				printf("%d %d\n", v.first, v.second);
			}
		}
		else {
			puts("-1");
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值