寒假训练2024/1/27

2024/1/27

uva120

题意:

给一个序列,给定一个序列的反转方式,要求用最少的次数把序列反转成升序

思路:

看到定级是个橙题,我以为就是简单的看头尾反转,因为样例给的很简单,按照猜测乱写了一个,WA了。

看了一眼udebug,发现不是简单的头和尾是所需要的数字。

我们需要先从大的数字开始,这是因为反转的特性,可以不管后面的数,然后处理次大值。

那问题1,对于xxxxoxxx如何把o移动到最后?

我们要先把o移动到最前端,然后反转到正确的位置。

过程是这样xxxxoxxx -> oxxxxxxx -> xxxxxxxo

然后写了代码交上去,RE了。

我测试了udebug的第一个代码,发现最后几个样例确实没跑出来,一看才发现,序列不一定是1 到 n

#include <bits/stdc++.h>
using namespace std;

void solve(string st) {
	vector<int>v;
	int num;
	stringstream is(st);
	while(is >> num) {
		v.push_back(num);
	}
	auto vv = v;
	sort(vv.begin(), vv.end());

	int n = v.size();
	for (int i = 0; i < n; i++) {
		if(i)
			cout << " ";
		cout << v[i];
	}
	cout << endl;

	auto f =[&] (int x) {
		int pb1 = 0, pb2 = n - x;
		while(pb1 < pb2) {
			swap(v[pb1++], v[pb2--]);
		}
	};

	int cnt = 1;
	for (int i = n; i >= 1; i--) {
		int loc;
		for (int j = 0; j < n; j++) {
			if(v[j] == vv[i - 1]) {
				loc = j + 1;
				break;
			}
		}
		if(loc == i) {
			cnt++;
			continue;
		}
		else {
			if(n - loc + 1 != n && n - loc + 1 != 1) {
				f(n - loc + 1);
				cout << n - loc + 1 << " ";
			}
			f(cnt); 
			cout << cnt << " ";\
		}
		cnt++;
	}
	cout << 0 << endl;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);

	string s;

	while(getline(cin, s)) {
		solve(s);
	}

	return 0;
}
posted @ 2024-01-28 14:03  contiguous  阅读(12)  评论(0编辑  收藏  举报