2022蓝桥杯省赛简要题解+复盘(C++ A组)

4.28 update:这都能压线省一?


与其说写题解,不如说是自己场上心里完全没数,下来想一遍发现T1(没加周围4刀),T2(把放满的状态当成了先手败,惯性思维了属于是),T4,T6(漏写更新条件)都挂了,心态爆炸. OI赛制恐怖如斯,估计只有60分了,连国赛都去不了了。
该好好反省下自己做题浮躁的习惯了,上次CSP就两眼出思路的T4也是卡了两小时,导致没时间做T3。更远的追溯到南京,2h12min第一发交H的树形dp,思路没错,因为写错变量名卡到4h24min(就是这么离谱),下来看了看1h内解决掉I,也算痛失银牌。。虽说acm不像OI,但也要少吃罚时少卡题。

另外第一次学对拍,附上对拍代码:

int main(){
    while(1){
        system("gen.exe > in.txt");
        system("E.exe < in.txt > out1.txt ");
        system("baoli.exe < in.txt > out2.txt ");   //baoli中间不能有空格,不然命令行识别不了
        if(system("fc out1.txt out2.txt")) break;
    }
}

A

法一:dp,记dp(r,c)表示切割一块r行c列的最少次数(没算外围的四刀),转移方程:

dp(r,c)=min(1+dp(r-i,c)+dp(i,c)), 1<=i<=r-1;

dp(r,c)=min(1+dp(r,c-j)+dp(r,j)), 1<=j<=c-1;

最后答案:dp(20,22)+4;
法二:考虑每条要切割的边(如图中红线,长度为1),如果一次只能切割一条边,答案就是边数=21 * 20+19 * 22;
不过显然可以一次切多条边。考虑每个交点对节省切割次数的贡献,对于每个交点,最优的方法是要么横着,要么竖着切,只能选一种,1次切了2条,使次数-1。那么答案 - = 交点数 (19 * 21) 。
在这里插入图片描述

B
博弈论+状压dp.
用8位2进制数记录8个格子的状态,每位上为1代表对应方格被选,0代表没被选。dp[i]=1时代表i为先手必胜态。
博弈论基础可知,先手必败态可转移到若干先手必胜态,而转移过后的状态标号一定小于原标号,故倒序做一遍即可。
Code:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define IOS {cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);}
#define ll long long
#define P pair<int,int>
int t[]={1,2,4,8,16,32,64,128,3,6,12,48,96,192};
int dp[256];//当前情况下先手是否必胜
int main(){
    dp[255]=1;  //场上读假题了,惯性思维以为谁放不了谁输..
    per(i,255,0){
        if(!dp[i]){
            rep(j,0,13){
                if((i|t[j])==i )dp[i^t[j]]=1;
            }
        }
    }
    cout<<dp[1]<<dp[3]<<dp[2]<<dp[6]; //实际上此时小蓝是后手
}

C
全场最简单的送分题感觉。
记sum为n个数之和。对于特定i, ∑ j = 1 n a i ∗ a j \sum_{j=1}^na_i*a_j j=1naiaj = a i a_i ai * (sum- a i a_i ai);
考虑每对积算两次,则2 * ans= ∑ i = 1 n a i \sum_{i=1}^na_i i=1nai*(sum- a i a_i ai).
或者想不到算两次的话,遍历的过程中维护sum即可。

D
从D题开始怎么难度就上来了啊。。。。(第一次参赛,天真的我还以为真的是暴力杯,题目会很水(bushi))
题面:
在这里插入图片描述
大致想法是对 a l a_l al^ a r a_r ar=x 的一对(l,r)更新区间,即左端点位于[1,l],右端点位于[r,n]的询问是yes,比较常见的离线套路。
做法:离线询问,并按右端点从左到右对询问排序。从左向右遍历,遍历到i时,将i视为 a l a_l al^ a r a_r ar=x 的(l,r)中的r。对于前面所有的 a l a_l al^x= a r a_r ar,只考虑最靠右的 a l a_l al即可,这个由于数据范围小可以用一个数组实现。
那么右端点>=i的所有询问,如果左端点<=l即为yes。由于询问是按右端点排序的,统计询问答案也是随着遍历有序的。

E
期望dp+逆元
d p i dp_ i dpi为爬到高度i时的期望时间,直接上式子:
d p i − 1 dp_ {i-1} dpi1=(1- p i p_i pi)* d p i dp_i dpi + p i p_i pi * d p 0 dp_0 dp0 + 1;
显然 d p n dp_n dpn=0,那么我们可以得到n个关于 d p 0 dp_0 dp0 d p n − 1 dp_{n-1} dpn1的式子,解出 d p 0 dp_0 dp0即可。
发现 d p n − 1 dp_ {n-1} dpn1式子右边只与 d p 0 dp_ 0 dp0有关,把 d p n − 1 dp_ {n-1} dpn1带入 d p n − 2 dp_ {n-2} dpn2,再把 d p n − 2 dp_ {n-2} dpn2带入 d p n − 3 dp_ {n-3} dpn3 … 每一项都是 d p i dp_ i dpi= 系数* d p 0 dp_ 0 dp0+ 常数。 最终 d p 0 dp_ 0 dp0=系数* d p 0 dp_ 0 dp0+ 常数。

F
在这里插入图片描述
首先,要求的是最低跳跃能力,一眼二分。
然后注意到,从左向右和从右向左跳是等效的。于是转化为从0跳到n,可跳>=2*x 次。
又想到,对于当前所在的点和给定的跳跃能力,贪心地尽可能跳到最右的一定最优。
做法:check(跳跃能力k)即可:
d p i dp_i dpi 为从i往后跳能上岸的最多次数。首先 d p i dp_i dpi<= H i H_i Hi; 然后 d p i dp_i dpi 先找最右边能到的 d p i + k dp_{i+k} dpi+k, 如果 d p i + k dp_{i+k} dpi+k不能满足则把 d p i + k dp_{i+k} dpi+k 的次数全给 d p i dp_i dpi,再往左找下一个[i,i+k]范围内最大的。最终判断 d p 0 dp_0 dp0>=2 * x;
d p i dp_i dpi加的同时,记得 d p i + k dp_{i+k} dpi+k要减。 找最右边能跳到的石头可以用set维护。check的总复杂度O(nlogn).

G
题意:长度为n的序列,可修改一个长度为k的连续段(修改成同一个任意值),求修改后的最长不下降子序列。
解法:首先枚举修改的是哪一段,那么修改这一段后,答案就是把这一段左边和右边拼起来的最长不下降子序列长度+k。可以枚举左端点,在左端点不断右移的过程中,维护左边段的最长上升子序列,可以维护得到 <=任意值 的最长不上升子序列长度(线段树区间修改,区间max查询)。

H
计算几何。注意极角排序用叉积,不能引入误差。
比较暴力,线段树维护区间max+二分即可。

I
给定T(T<=1e5)个正整数ai(ai<=1e18),每个ai问能否表示为 x 1 y 1 x_1^{y_1} x1y1 * x 2 y 2 x_2^{y_2} x2y2 的形式,必须保证 y 1 y_1 y1, y 2 y_2 y2>=2,且四个数均为整数。
解法:
首先很重要的性质:如果是yes,一定存在 x 1 2 x_1^2 x12 * x 2 3 x_2^3 x23 的形式。证明:可以假设指数>3,那么一定可以写成2 * k+3或者2 * k的形式。
接下来考虑 x 1 x_1 x1, x 2 x_2 x2中较小的一个,易知其 <= 1 e 1 8 0.2 1e18^{0.2} 1e180.2,记M= 1 e 1 8 0.2 1e18^{0.2} 1e180.2
那么可以枚举M以内的质数(549个)作为ai的质因子,除完后剩下的数一定只能是某数的平方或三次方,否则不和题意。对于M以内的每个质因子,判断其幂次只要不为1即可分配到 x 1 2 x_1^2 x12 * x 2 3 x_2^3 x23中。

J
听说原题一眼题,可我只会暴力555,咕。
要知道[l,r]的部分和,其实就是知道sum[r]-sum[l-1].(sum代表前缀和)
那么对于M个已知条件,每个条件对l-1,r连边,那么知道sum[r]-sum[l-1]等同于r,l-1联通。带权并查集维护即可。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值