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; }