2018NOIP第五次膜你赛
传送门
第一题 反蝴蝶效应
题意
有$n$个点,我们需要走过这些点仅$1$次,到点$i$时你的身上必须有$a_i$的能量。在那之后,你的能量会$-1$。求你开始时需要的最小能量值。
题解
算法一:二分。
算法二:输出$\max_{i=1}^{n}\left(a_i+i-1\right)$
input() print(max(i+j for i,j in enumerate(map(int,input().split()))))
第二题 贝伦卡斯泰露
题意
给出一个长度为$n$的数列$A_i$,问是否能将这个数列分解为两个长度为$n/2$的子序列,满足
- 两个子序列不互相重叠。
- 两个子序列的数要完全一样,$\{1,2\}=\{1,2\},\{1,2\}\not=\{2,1\}$。
$T\leq 5,1\leq A_i\leq n\leq 40$,保证$n$为偶数。
题解
我太蒟蒻了,所以dfs水过了此题。。
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
int n;
int a[45];
vector<int> v1, v2;
bool dfs(int x, int y) {
if (y > n/2) return false;
if (n-x+1+y < n/2) return false;
for (int i=0; i<min(v1.size(), v2.size()); i++) if (v1[i] != v2[i]) return false;
if (x == n+1) return y == n/2;
v1.push_back(a[x]); if (dfs(x + 1, y + 1)) return true; v1.pop_back();
v2.push_back(a[x]); if (dfs(x + 1, y)) return true; v2.pop_back();
return false;
}
bool pre_spr() {
/*int cnt[45];
for (int i=1; i<=40; i++) cnt[a[i]]++;
for (int i=1; i<=40; i++) if(cnt[a[i]] & 1) {
n=2; a[1]=1;a[2]=2;
return true;
}*/
return false;
}
bool do_spr(int x) {
for (int i=1; i<=20; i++)
if (a[i] != x) return false;
n=20;
for (int i=1; i<=20; i++) a[i]=a[i+20];
return true;
}
int main() {
//freopen("split.in", "r", stdin);
//freopen("split.out", "w", stdout);
int T; scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i=1; i<=n; i++) scanf("%d", &a[i]);
v1.clear(); v2.clear();
if (!pre_spr() && n==40) for(int i=1; i<=40; i++) if(do_spr(i))break;
if (!dfs(1, 0)) puts("Furude Rika");
else puts("Frederica Bernkastel");
}
return 0;
}
浙公网安备 33010602011771号