标题是真的,因为我太菜了。
九月十三号开了坑,然后其实我的脑子经常丢失,每次感觉自己会的硬是在考场上想不到,属实鬼畜。然后我数学也不咋的,除了是个超级耐酸王别无长处。
反正写着玩玩,自己已经清楚的知道结局了。
中秋节前一天打了梦熊jason round, 被简单题卡了,然后J只拿了341pts,随后回老家,当晚发烧了,然后到9月19号一直状态低迷,我妈妈就把我接回来了。乐死我了这个状态还能考初赛?
初赛了,用脚趾做完了,结束后发现ccf怎么还能出ub的啊。这是J组
然后下午S组阅读理解马蜂抽象没看懂,位运算不太会,但是那个T1的位运算开始算的是按位或选B,后来改成D。阅读程序开始全选的A,然后认为不可能这么搞,然后改了两个。事实证明我错了,选择题就丢了9分。判断题也不知道丢了多少。最后56pts。
然后国庆和弟弟玩了一把方块人干架,乐死我了。
10月2号集训,傻子gghack又是J组,老师画大饼说考得好可以加入联测,然后我只拿了300pts,60+100+80+60,本来应该可以AK的,但是没判无解+饭堂+果断弃掉正解打暴力结果忘删调试,zjz,zjh,hcy,rj全部考联考去了。
咱就是说这个大饼好像吃不到(
10月3号考试T1没切掉,其实考场上已经发现了这样一个很显然的结论,可是我以为它只有在判定无解时有用,然后就没打出来
T2暴力链表写了巨大臭依托,然后RE了,乐。
T3开题只有20min了,30pts跑路
T4开题只剩2min了,想都来不及想。
总结:花3h获得了0pts,花27min获得了30pts。
由于这次比赛打的太孙就放一下题面:
T1:给定每个数位的出现次数 a_i,求最小的满足数位限制的数数使得相邻各位不相同,且不含有前导0。
解析:可以发现一个很傻子的性质判断能否构成:
设 \sum a_i=S,mx=\max\{a_i\},则 mx\leq S-mx+1 才能构成上文数字,然后贪心取即可。
# include <bits/stdc++.h>
using namespace std;
int a[10];
pair<int,int> chkmx() {
int maxx = 0,id;
for (int i = 0;i <= 9;++i)
if (maxx < a[i]) maxx = a[i],id = a[i];
return make_pair(maxx,id);
}
void solve() {
int sum = 0,flag = 0,pre = 0,cnt = 0,qur = 0;
for (int i = 0;i <= 9;++i) cin >> a[i],sum += a[i],cnt += (a[i] > 0);
if (cnt == 1) {
if (sum > 1) return cout << "-1\n",void();
else for (int i = 0;i <= 9;++i) if (a[i]) return cout << i << '\n',void();
}
deque<int>ans;
for (int i = 1;i <= sum;++i) {
bool ifchoose = 0;
for (int j = 0;j <= 9;++j) {
if (!a[j]) continue;
if (!j && !flag) continue;
if (j == pre) continue;
--a[j];
pair<int,int> gg = chkmx();
if (gg.first <= sum - gg.first - qur) {++qur,pre = j,flag = ifchoose = 1,ans.push_back(j);goto penguly;}
else ++a[j];
}
if (!ifchoose) return cout << "-1\n",void();
penguly:;
}
if (!flag) return cout << "-1\n",void();
while (!ans.empty()) cout << ans.front(),ans.pop_front();
cout << '\n';
}
signed main() {
int T;
cin >> T;
while (T-->0) solve();
}
/*
123234345454565656767676787897979898989898989
123234345454565656767676787897979898989898989
*/
当天晚上洗澡时发现结论只有在填了一个数字之后才适用。
T2:
然后 $a_i$ 较大者胜出,对于每个 $i$,求如果 $i$ 有一个复活图腾(即第一次死的时候判定他赢),则 $i$ 的排名是?
排名:$\frac{n}{2}+1$,其中除法向上取整。
建树直接往上跳就行。
```cpp
# include <bits/stdc++.h>
#define int long long
using namespace std;
const int __ = 5 * 500005;
int a[__],n,node;
vector<int>larsr;
int fa[__];
vector<int>g[__];
int jump(int x) {
vector<int>change;
int cnt = 0,xx = x,pos = 0,yuan = 0;
bool flag = 0;
int sz = n;
while (x != node) {
int F = fa[x],maxx = 0;
// cout << F << ":";
for (auto y : g[F]) maxx = max(maxx,(a[y] == yuan?a[xx]:a[y]));
// cout << "\n" << "--------\n";
// cout << maxx << " " << F << ' ' << sz << ' ' << flag << '\n';
if (maxx == a[xx] || g[F].size() == 1) x = fa[x];
else if (!flag) x = fa[x],flag = 1,yuan = a[F];
else return sz / 2 + (sz & 1) + 1;
sz = (sz & 1) + (sz / 2);
}
return 1;
}
signed main() {
// freopen("match.in","r",stdin);
// freopen("match.out","w",stdout);
cin >> n;
for (int i = 1;i <= n;++i) cin >> a[i],larsr.push_back(i);
int gg = n,gg2 = n;
node = n;
while (gg > 1) {
vector<int>fb;
for (int i = 0;i < larsr.size();++i) {
if (i % 2 == 0) ++node,fb.push_back(node);
fa[larsr[i]] = node;
g[node].push_back(larsr[i]);
a[node] = max(a[node],a[larsr[i]]);
// cout << "儿子 " << larsr[i] << "belongs to " << node << " 这个甲方爸爸\n";
}
larsr.clear();
for (auto x : fb) larsr.push_back(x);
gg = gg / 2 + (gg & 1);
}
// cout << jump(7) << '\n';
for (int i = 1;i <= n;++i) cout << jump(i) << ' ';
return 0;
}
```
T3:P8289
T4:简单背包。
之后就是练习,10.5号打了牛客S组,T1我10min推出来了,然后由于不能说的秘密导致我又瞪了50min,开T2,问出题组题意,他说让我自行理解,可是我觉得1->3的最长路明明是2,他说是1?
然后开T3,直接把出题组给的图全部扔上去了。
T4写了个 $O(nm\times 玄学)$ 的做法,没想到30pts。
然后又看T2,写了一个假的要死的做法,没交,后来发现可以拿50pts,难评。
后期进了C3机房,成为了入机:三次测试加起来分数没到100pts。我是真的不会,跟瓜分没一点关系。
然后就快到 AFO 的日子了,记录一下10.21号的模拟赛吧。
T1:
有一个序列 $\{x_n\}$,$\forall x_i\in \{1,2,3\}$。
非空子序列是一个集合 $S\subseteq \{1,2,\cdots,n\}$,一个非空子序列是非空不连续子序列当且仅当其不是非空连续子序列,即 $\exist \min S \leq i \leq \max S,i\notin S$。(注意,存在即可!我看成了对于任意一个!)
如果他是好的,那么 $\exist c\in \{1,2,3\},\sum\limits_{i\in S} [x_i=c] \geq \frac{|S|}{2}$,如果说他是完美的当且仅当他的每一个非空不连续子序列都是好的。长度 $\leq 2$ 的必然是完美的。
现在问你,如果把一段区间 $[l,r]$ 拿出来,将 $0$ 改成 $1,2,3$ 的方案中,有多少种使得改完之后 $[l,r]$ 是完美的。
首先如果区间长度大于等于 $5$,条件就等价成了让三个数不能同时出现,因为三个数同时出现就会至少有一个长度为 $3$ 的区间为 $\{1,2,3\}$ 的一个排列。
那么长度小的时候直接暴力,大的时候记区间 $0$ 的个数为 $k$:
- 三个数出现,答案为 $0$。
- 两个数,例如为$\{1,0,0,1,1,0\}$,那么 $0$ 的位置填 $1/2,1/3$ 都算一种方案,同时会填重复那个出现过的数,方案数量为 $2^k+2^k-1$。
- 一个数同理,为 $2^k+2^k+2^k-3$。
然后比赛了,1min切了T1,T2看错题以为是搜索,结果就是按照题意模拟。
T3打了一个记忆化,不知道会不会MLE,本地测试会爆栈(悲)。
T4打了一个类似于 dp 的算法,但是开了 $10^6$ 个 set。比较惊悚。
后面就在检查,忘记T3当 $n=10$ 的时候我的程序输出什么了。
S组爆了。
开考,T1一眼想到贪心,然后敲了一个发现过不去最大的样例,再仔细读了一遍题+瞎改了一下发现我理解错了。
T2跳了,打T3暴力+dp,怎么说呢,我只设了一维状态,然后用一个数组记录从哪里转移过来,然后只能过小样例,有没有大佬帮我看一下:
$f_i$ 表示到 $i$ 点填红色的最大价值,后面全部填蓝色。
$f_i=\max\limits_{j < i}\{f_j+sum(j+1,i-1)\}
T4没看,后面开了T2,思索了一下打了20pts,发现40pts打出来之后60pts也打出来了,然后就A了,但是我 $a_i>0$ 不知道怎么出了玄学错误,直接拜拜了。
赛后发现好像 $a_i=0$ 的也打错了,乐。
最后估分:J组 $100+100+[30,70]+[0,60]=[230,330]$。
S组: $100+[0,20]+20+0=[120,140]
不得不说简直看不了,但是我还有时间,我可以继续,明年再来吧。
出分:
J组 100+0+30+60=190。
S组: 100+0+20+0=120