C. Min Max Sort
题目大意
给定一个长度为n的排列p(长度为n的排列是一个长度为n的数组,其中从1到n的每个整数恰好出现一次)。您可以执行以下操作任意次数(可能为零):
- 选择两个不同的元素和y,并将它们从排列中删除;
- 将z和y的最小值插入到排列中,使其成为第一个元素;
- 将z和y的最大值插入到排列中,使其成为最后一个元素
问最少通过几次操纵可以使排列递增
题目分析
如果当前序列有序,则操作次数为0,当其无序的时候,我们要进一步进行思考
假设序列完全序,则我们最后一次的操作数必然为1
与n
,倒数第二次选取的操作数为2
与n-1
,以此类推则第一次的操作数为(n+1)/2
与(n+2)/2
(由于向下取整的特性,使奇数也能正确找到中间数)
若每一对都要进行操作则需n/2
次操作。从第一次的数对开始判断有多少对不用进行操作(即其位置一符合要求),则剩下的即为需要操作的次数。
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, k, t;
int f[N];
void solve()
{
cin >> n;
for(int i = 1; i <= n; i ++)f[i] = 0;
for(int i = 1; i <= n; i ++)
{
cin >> m;
f[m] = i;
}
int l = (n + 1) / 2, r = (n + 2) / 2;
while(l > 0 && (l == r || (f[l] < f[l + 1] && f[r] > f[r - 1])))
l --, r ++;
cout << (n - (r - l) + 1) / 2 << "\n";
}
int main()
{
cin >> t;
while(t --) solve();
return 0;
}
C. Skier
题目大意
滑雪者在雪地上滑行。它的运动可以用一串字符“s”、“N”、“w”、“E”来描述(分别对应南、北、西、东方向1米的运动)。我们知道,如果他沿着一条路径的一个以前未被访问的部分移动(即这段路径是第一次被访问的),那么这种移动的时间是5秒。如果他沿着之前访问过的路径段滚动(即,这段路径之前已经被他的路径覆盖过),则需要1秒。找出滑雪者滑完所有路径的时间。
题目分析
第一次经过某边贡献值为1,重复经过某边每次贡献值为5,判断每一个边是否重复经过累加相应的贡献值即可。
code
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
int n, m, k, t;
string s;
void solve()
{
cin >> s;
map<pair<PII, PII>, int>q;
ll ans = 0;
int rx = 0, ry = 0;
for(int i = 0; i < s.size(); i ++)
{
int nx = rx, ny = ry;
if(s[i] == 'S') ry -= 1;
else if(s[i] == 'N') ry += 1;
else if(s[i] == 'W') rx -= 1;
else if(s[i] == 'E') rx += 1;
if(q[{{nx, ny}, {rx, ry}}]) ans ++;
else ans += 5;
q[{{nx, ny}, {rx, ry}}] ++;
q[{{rx, ry}, {nx, ny}}] ++;
}
cout << ans << "\n";
}
int main()
{
cin >> t;
while(t --) solve();
return 0;
}
C. Friends and Gifts
题目大意
有n个朋友想要互赠新年礼物。每个朋友只能送一份礼物,也只能收到一份礼物。朋友不能把礼物送给自己。对于每个朋友,f值都是已知的:如果第i个朋友不知道他想把礼物送给谁,填补fi=0处使得每个朋友只赠送一份礼物,也只收到一份礼物,并且没有朋友将礼物送给自己。保证初始信息不矛盾。如果有几个答案,你可以打印任何一个。
题目分析
因有一对一的前提,所以我们可以将未送出的和未收到的分别存储,再进行匹配,若碰到同一个人的情况,换一个匹配即可
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, k, t;
int a[N];
bool st[N];
void solve()
{
vector<int>p, q;
cin >> n;
for(int i = 1; i <= n; i ++)
{
int u;
cin >> u;
a[i] = u;
st[u] = true;
}
for(int i = 1; i <= n; i ++)
{
if(!a[i]) p.push_back(i);
if(!st[i]) q.push_back(i);
}
for(int i = 0; i < p.size(); i ++)
{
if(p[i] == q[i])
swap(q[i], q[(i + 1) % p.size()]);
}
for(int i = 0; i < p.size(); i ++)a[p[i]] = q[i];
for(int i = 1; i <= n; i ++) cout << a[i] << " ";
puts("");
}
int main()
{
solve();
return 0;
}