Crane UVA - 1611 思路+构造】的更多相关文章

题目:题目链接 思路:思路+构造,假设 i  在pos 位置,那么如果 (pos-i-1)*2+i+1 <= n,那么可以操作一次换过来,如果他们之间元素个数是偶数,那么交换 i - pos,如果是奇数,交换 i - pos+1,然后再经过一次就可以换到指定位置,如果是奇数并且pos==n,先与前一个元素交换一下,然后执行前面的操作. AC代码: #include <iostream> #include <cstdio> #include <algorithm>…
这道题和例题8-1相当的像. 例题8-1https://blog.csdn.net/qq_34416123/article/details/80112017 一开始我还以为用归并的思想, 用交换把局部交换好, 然后再整体交换 花了一个一小时好不容易写好之后, 发现我这种解法局部有序并不能保证整体有序. 因为归并排序的局部是连续的, 是1 2 3 4 5这样的, 然后我这种方法局部排出来只能 1 3 5 6这样的, 所以最后合并不能保证整体有序-- 然后提示是2n次就够了.这个提示一开始没看懂啥意…
题目链接 题意: 一个序列,你可以选择其中偶数长度的一段,然后中间切开,左右两段交换.现给你一个1~n的某个排列,求一个交换方案,使得排列最终有序.(交换次数 < 9^6) 思路: 从左到右,依次把一个个数放到位.把一个数放到正确的位置,观察发现最多两步.第i个数,若现在的位置在 [i+1, (n+i)/2] 内,则可以一次到位.若在它右边,则可以通过一次,使得其到这个范围内. 代码: #include <cstdio> #include <cstring> #include…
题意:给定一个序列,让你经过不超过9的6次方次操作,变成一个有序的,操作只有在一个连续区间,交换前一半和后一半. 析:这是一个构造题,我们可以对第 i 个位置找 i 在哪,假设 i  在pos 位置,那么如果 (pos-i)*2+i-1 <= n,那么可以操作一次换过来, 如果不行再换一种,如果他们之间元素是偶数,那么交换 i - pos,如果是奇数,交换 i - pos+1,然后再经过一次就可以换到指定位置. 代码如下: #pragma comment(linker, "/STACK:1…
题目: 输入一个1~n(1≤n≤300)的排列,用不超过96次操作把它变成升序.每次操作都可以选一个长度为偶数的连续区间,交换前一半和后一半.输出每次操作选择的区间的第一个和最后一个元素. 思路: 注意紫书上的提示,2n次操作就可以完成了.从头开始遍历序列,属于该位置上的元素,可以在两步之内交换到这里. #include <bits/stdc++.h> #define inf 0x3f3f3f3f #define MAX 1e3 #define FRE() freopen("in.t…
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 想把数字i从位置j移动到位置i 可以这样. 假设mov(x,y)表示将(x..x+len/2-1)和(x+len/2..y)交换. 则可以先进行mov(j,i-1)操作. (如果(j,i-1)的长度为奇数,终点就变为i-2) 令len = (i-1)-j+1 //当然长度为奇数的时候就是(i-2)-j+1了 x = j+len/2 =>x就是数字i新的位置 然后令len2 = i-x; 然后再进行一次mov(x-len2+1,i…
假设数字1~i-1已经全部归位,则第i到第n个数为无序区间. 如果i在无序区间的前半段,那么直接将i换到第i个位置上. 否则先将i换到无序区间的前半段,再将i归位.这样每个数最多操作两次即可归位. #include <bits/stdc++.h> using namespace std; + ; int a[maxn]; vector<pair<int, int> > ans; void op(int L, int R) { ans.push_back(make_pai…
题意: 输入一个1-n的排列,要求经过操作将其变换成一个生序序列.操作的规则如下每次操作时,可以选一个长度为偶数的连续区间,交换前一半和后一半. 分析: 假设操作到第i个位置,而i这个数刚好在pos这个位置上,现在就要判断一下能否直接将pos上的i经过操作调到i这个位置上.如果 i + (pos - i) * 2 - 1 <= n 就表示可以一次操作完成.在上面条件不成立的情况下,又分为两种情况:一种是pos和i的距离是奇数的情况:那么就直接将[i,pos]这个区间的值进行交换即可.另一种是距离…
题意:给一个1~n排列,1<=n<=10000,每次操作选取一个长度为偶数的连续区间.交换前一半和后一半,使它变成升序. 题解:每次只要把最小的移动到最左边,那么问题规模就缩小了.假设当前区间为[l,r],不难发现,只要最小的数字在[l,l+(r+1-l)/2]这个区间内,一定可以通过一次交换把最小的数字移动到l处,否则,先一定可以一次交换把最小的数字移动到上述区间中. #include<bits/stdc++.h> using namespace std; ; int a[max…
题意:输入一个1~n(1<=n<=10000)的排列,用不超过9^6次操作把它变成升序.每次操作都可以选一个长度为偶数的连续区间,交换前一半和后一半. 提示:2n次操作就足够了. 分析:从左到右依次将数字i放在位置i. 设要将数字i放在位置i,而数字i现在在位置pos. (1)若(pos - i) * 2 + i - 1 <= n,则可以直接将i放在位置i.pos-i为连续区间的一半长度,i-1为i之前已经排好的数字个数.交换连续区间(i, i + (pos - i) * 2 - 1)…