$NOIp$做题记录

虽然去年做了挺多了也写了篇一句话题解了但一年过去也忘得差不多了$kk$

所以重新来整理下$kk$

$2018(4/6$

[X]积木大赛

大概讲下$O(n)$的数学方法.

我是从分治类比来的$QwQ$.考虑对每个点,如果它左侧比它高,显然可以在左侧被消的时候顺便把它消了.

否则只能消到左侧那个高度.

所以答案为$sum max(0,a_i-a_{i-1})$

[X]货币系统

一个结论:显然是从原来的集合中选出一个子集来.

我也不记得我怎么在考场上就突然想到这个结论了,,,感觉也挺显然的.所以也没啥严谨证明$QwQ$.

$luogu$题解里好像有个证明我有时间看下然后补上$QwQ$

反正知道这个结论之后就直接从小到大排序跑个背包就成$QwQ$.

[X]赛道修建

,,,一年过去了$gql$还没落实$kk$

写下大概思路趴$QwQ$.

首先显然是二分.然后现在就是要$check$长度大于等于$mid$的道路数量是否大于等于$m$.

$dfs$遍就好.从小到大枚举能成道路就成道路,然后把剩下的最长的传上去,$over$

我我我比较懒写的$multiset$.在$luogu$要开$O2$

[X]旅行

,,,一年过去了$gql$还没落实$kk$

发现只有树和基环树.

如果是树就很$easy$?每次跑到尽量小的就好$QwQ$.

然后基环树.

一个显然的想法是枚举断环上哪条边然后分别做树.

但是这样的做法的复杂度是$O(n^2)$,就不能通过加强版.所以港下$O(nlogn)$的做法$QwQ$

首先显然会被影响的只有在环上的操作,那就只看环了.

发现一个显然的结论是当.当前节点只有环上的儿子节点没有被访问,且当前节点环上祖先的未被访问最小儿子小于自己那个没有被访问的儿子节点时才会返回.

虽然句子很长但显然还是挺显然的$QwQ$.然后就做完了$QwQ$.

虽然但是太麻烦了我写个$O(n^2)$就跑路了.记得找环不然会$T$成$88pts$,$QAQ$

#include<bits/stdc++.h>
using namespace std;
#define rp(i,x,y) for(int i=x;i<=y;++i)

const int N=50000+10;
int n,m,head[N],ed_cnt,banx,bany,fr[N],to[N],instck[N],stck[N],top;
bool vis[N],gdgs[N],flg;
vector<int>V[N],as,tmp;

vector<int> mn(vector<int>gd,vector<int>gs)
{if(!((int)gd.size()))return gs;rp(i,0,n-1)if(gd[i]<gs[i])return gd;else if(gd[i]>gs[i])return gs;return gd;}
void cal(int nw)
{
    tmp.push_back(nw);vis[nw]=1;if((int)tmp.size()==n){as=mn(as,tmp);return;}
    int sz=V[nw].size();rp(i,0,sz-1)if(!vis[V[nw][i]] && !(banx==nw && bany==V[nw][i]) && !(bany==nw && banx==V[nw][i]))cal(V[nw][i]);
}
void dfs(int nw,int f)
{
    instck[nw]=1;stck[++top]=nw;int sz=V[nw].size();if(flg)return;
    rp(i,0,sz-1)if(V[nw][i]^f)if(!instck[V[nw][i]])dfs(V[nw][i],nw);else{while(stck[top]^V[nw][i])gdgs[stck[top--]]=1;gdgs[V[nw][i]]=1;flg=1;}
    --top;instck[nw]=0;
}

int main()
{
    freopen("travel.in","r",stdin);freopen("travel.out","w",stdout);
    scanf("%d%d",&n,&m);rp(i,1,m){int x,y;scanf("%d%d",&x,&y);V[x].push_back(y),V[y].push_back(x);fr[i]=x,to[i]=y;}
    rp(i,1,n)sort(V[i].begin(),V[i].end());;if(m==n-1){cal(1);rp(i,0,n-1)printf("%d ",as[i]);return 0;}dfs(1,1);
    rp(i,1,m){banx=fr[i],bany=to[i];if(!gdgs[banx] || !gdgs[bany])continue;tmp.clear();memset(vis,0,sizeof(vis));cal(1);}rp(i,0,n-1)printf("%d ",as[i]);
    return 0;
}
View Code

[ ]填数游戏

先预警下,,,我本来是想,认认真真写下证明的.然后.越写越懒到最后就全是结论了$QwQ$

下面这段不重要,直接来看结论趴.

先证几个结论.

结论一:交换$n$和$m$,答案不变.

正确性显然,,,?这个不证了$QwQ$.然后有了这个结论之后,为了方便后文全部默认$nleq m$.

结论二:每条对角线上的数单调不增.

这个也是显然,,,?不证了$QwQ$

结论三:每条对角线上相邻且相同的点,它们右下方的矩形区域一定满足每条对角线上的数都相等.

考虑反证法,找到两条路径在第二次分叉前字典序一直相等.发现若此时不相等一定非法是趴$QwQ$

然后接下来看题.我们先对$n$进行分类讨论.

若$n=1$,这个可以直接手推出来$ans=2^m$.

若$n=2$,这个手玩下不难发现答案为$4cdot 3^{m-1}$(每个对角线有$3$种方案,左上右下有$2 imes 2=4$种方案

若$n=3$,这个等下考虑.

若$ngeq 4$,再分四种情况考虑.

$case 1$.最上面对角线两个数填数相同.

$case 2$.最上面对角线两个数不同,下一行对角线三个数填数相同

$case 3.$都不同,且第二行对角线填数为$1,0,0$.

$case 4.$都不同,且第二行对角线填数为$1,1,0$

因为都有对角线相邻相等的条件所以能限制一大片区域,手玩下可以发现一个结论是,对于$ngeq 4$且$mgeq n+1$,有$ans(n,m+1)=3 imes ans(n,m)$

证明结合图像和限制条件啥的不难得到$QwQ$

然后现在考虑$n=m$,按上面的分类讨论颓柿子.

$case 1:ans=2 imes 2 imes 4^{n-2} imes2^{n-1}=8^{n-1}$(左上格子和第一行对角线分别有$2$种方案,之后$n-2$行对角线都是除了两侧两个格子外全被限制了,分别是$4$种方案,直到最长的那条对角线.之后的$n-1$条对角线都是整个被限制了,所以是$2$种方案.

$case 2:ans=2 imes 2 imes 5 imes 4^{n-4} imes 2^{n-1}=5 imes 2^{3n-7}$

同样是画图看下就能发现的结论不说.

然后$case 3$比较麻烦我懒得说了,,,$case 4$等价于$case 3$,,,我我我我就只说结论了.$ans=2 imes 4 imes 5 imes sum_{i=0}^{n-5}4^i imes 2^{n-1}+2 imes 4 imes 3 imes 2^{n-2}+2 imes 3 imes 2^{n-2}$

所以$ans(n,n)=ans_{case_1}+ans_{case_2}+ans_{case_3}+ans_{case_4}=frac{83 imes 8^n+5 imes 2^{n+7}}{384}$

然后$ans(3,m)=112 imes 3^{m-3},ans(n,n+1)=frac{83 imes 8^n+2^{n+8}}{128}$.没有证明只有结论$QwQ$.

最后整理下几个柿子趴.

$nleq 2$可能要特殊搞下,后面的数据就可以直接后面那个亚子变形了$QwQ$

$f_{n,n}=f_{n-1,n-1} imes 8-5 imes 2^n$

$f_{n,n+1}=f_{n,n} imes 3-3 imes 2^n$

当$mgeq n+2$或$m>8$时,$f_{n,m}=f_{n,n+1} imes 3^{m-n-1}$

 

[ ]保卫王国

,,,咕咕.

$2017(6/6$

[X]小凯的疑惑

昂大概港下数学证明趴,,,?

考虑现在要构造最大的不能被表示出来的数.设这个数为$x$.

因为$(a,b)=1$,所以$x$一定能用$x=pcdot a(mod b)(1leq pleq b-1)$表示出来.

于是设$x=pcdot a+qcdot b$.显然的是当$q>=0$时$x$就能用$a,b$表示出来了.所以$q_{max}=-1$.

然后因为$x$要尽量大,所以$x=p_{max}cdot a+q_{max}cdot b=(b-1)cdot a+(-1)cdot b=acdot b-a-b.$

$over$

(其实还有个很神的$exgcd$方法,,,是完完全全用$exgcd$做的没有猜结论啥的,,,但我没很$get$就没写了$kk$

$upd:$

用同余类最短路真的贼简单证明也贼好想$QwQ$.

具体看我<$NOIp2018$集训$ppt$落实博>

[X]时间复杂度

大模拟不说,注意细节就成$QwQ$

[X]逛公园

考虑先$dij$跑出最短路,然后设$f_{i,j}$表示当前决策到点$i$,浪费了$j$步的方案数,记搜就完事.

关于$0$环因为是记搜所以就每访问一个状态存到$stack$里面,如果本来就在$stack$里面了就说明有$0$环,最后出去的时候再从栈里丢出去就完事$QwQ$.

[X]奶酪

我是直接按高度排序,然后从所有能和上面/下面直接相连的洞$bfs$.

复杂度是$O(n^2),,,?$似乎是的$QwQ$.

[X]宝藏

$QwQ$我写了题解

我写的$dp$,设$f_{i,S}$表示当前决策到了第$i$层,点集状态为$S$的最小代价,转移下就完事$QwQ$.

复杂度不会算,,,$O($能过$)(bushi$

[X]列队

$QwQ$也写了题解

简单想法就给每一行及最后一列开一个$vector$,然后线段树维护第$i$个是$vector$上的第多少个.

然后就做完了$QwQQQQQQ$.

$2016(6/6$

[X]玩具谜题

大模拟就完事$QwQ$

[X]天天爱跑步

写了题解$QwQ$

把所有路径拆成两条,分别为$x-lca$和$y-lca$,现在只处理$x-lca$.

发现对点$i$,能观察到的点$j$都满足$dep_j=dep_i+w_i$,且$j$在$i$的子树中.

开个桶记录就欧克.

然后对于$y-lca$,基本类似只是式子不一样.

注意一下的是$lca$被统计了两次记得减回去.$over$

[X]换教室

好像也写了题解,,,太古早了就不放链接了$kk$.

设$f_{i,j,0/1}$表示考虑到第$i$节课了,进行了$j$次申请,当前申请了/没申请的最小期望.

转移就,分类讨论.

如果当前没申请,可以从上次没申请,$f_{i-1,j,0}+dis1$,和上次申请了,$f_{i-1,j,1}+kcdot dis1+(1-k)cdot dis2$

然后申请了差不多太长了不说了$kk$.

[X]组合数问题

恩直接做就完事,,,我也不知道咋说$kk$

就算出$C$然后前缀和下$QwQ$,$over$.

[X]蚯蚓

考虑开两个$vector$,一个存本来就有的,一个存每次砍了之后得到的.

发现第一个只要开始$sort$一遍,第二个一定是单调减的.

所以直接每次取开头比较就完事$QwQ$.

[X]愤怒的小鸟

两个方法,一个状压$dp$一个搜索.

出于某不知名原因我去年落实的状压$dp$并表示"搜索咋做啊我不会啊"然后今年考发现我只会搜索不会状压$kk$.

就只说搜索了鸭.

设$dfs(i,x,y)$,表示枚举到第$i$个了,有$x$条抛物线,$y$个单独被打的.

然后每次如果可以和抛物线一块打肯定和抛物线打就完事.否则可以从$y$个中选一个再构出一个抛物线,或者再加入那$y$个里面也是单独被打.

然后加个最优性剪枝就完事$QwQ$

$2015(6/7$

[X]神奇的幻方

大模拟就完事

[X]信息传递

发现一定是若干个不相交的环.

所以把环都跑出来,答案就是环的最短长度.

[X]斗地主

考虑爆搜.

每次只考虑进行一个操作,记录下每张牌用了几张,直接做就完事.

只要考虑有带操作的,其他几个单牌对子三排炸弹都可以当作散牌.

加个最优性剪枝就过了$QwQ$

[ ]斗地主进阶版

[X]跳石头

二分入门题,不说了$QwQ$

[X]子串

我我我我之前写了这题还写了题解,对这题印象蛮深的.

因为这题就一个简单$dp$就完事但是我思维僵化没想出来$kk$

考虑设$f_{i,j,k,0/1}$表示$A$中匹配到$i$,$B$中匹配到$j$,取了$k$个,第$k$个正在取/已经取完了的方案数.

如果选,首先需要$B_j=A_i$,转移就$f_{i,j,k,1}=f_{i-1,j-1,k,1}+f_{i-1,j-1,k-1,0}$

不选的话就没有任何限制,转移就$f_{i,j,k,0}=f_{i-1,j,k,0}+f_{i,j,k,1}$,这里为啥是$f_{i,j,k,1}$,是我可以强行这里选完了,即使后面接着选我也可以强行断开是趴$QwQ$

[X]运输计划

考虑二分,找出最长长度之后把所有长度不满足的路径的所有边打个$+1$标记,然后找出所有$+1$标记数量等于不满足路径数量的边,如果最长路径减去这条边的长度后小于等于二分的值就是欧克的.

树上打$+1$标记显然树剖之后直接差分就行嘛$QwQ$.

注意实际实现显然是给点打标记,所以在打代码的时候要清醒一点考虑哪个点对应的哪条边$QwQ$

$over$

$2014(6/6$

[X]生活大爆炸版石头剪刀布

模拟就完事,$QwQ$

太简单了啥技巧也没有不说了$kk$

[X]联合权值

有的题目,表面上说着自己是张图,其实就是一棵树$QwQ$

考虑满足这样联合权值关系的,一定要么是祖孙关系要么是兄弟关系.

于是考虑树形$dp$,对每个点记录儿子节点的和以及儿子节点的$max$.

然后取$max$直接做,求和用乘法分配率,然后就做完了$QwQQQQQ$

[X]飞扬的小鸟

考虑设$f_{i,j}$表示位于$(i,j)$的最小操作次数.

然后每次向上就是$f_{i,j}=f_{i,j-x_i}$,向下就是$f_{i,j}=f_{i,j+y_i}$.

柱子全设成$inf$就成.$over$

[X]无线网络发射器选址

发现数据范围都贼小,直接二维差分就完事$QwQ$

[X]寻找道路

首先$bfs$找到所有不能到达点$T$的点,所有指向$T$的点就都$GG$了.

然后再跑一遍$bfs$,只走能走的点就完事$QwQ$

[X]解方程

我好呆,,,我开始没注意数据范围,以为$O(nm)$过不去,还很难受我咋啥也不会,,,

然后就发现$O(nm)$过得去,$QwQ$.

发现现在的问题就在于$a_i$太大了$QwQ$.

考虑取膜,多设几个模数,如果都等于$0$就当作是等于$0$的$QwQ$.

设了模数之后用秦九韶就成$QwQ$,这个不难不说了$QwQ$

$2013(6/6$

[X]转圈游戏

模拟题.

先算出每个人挪了多少个位置,然后就能直接算出来了$QwQ$

[X]火柴排队

考虑先给$b$按$a$排序,然后题目就变成了,给定一个序列,每次可以两两交换,问最少有多少次可以使得序列从小到大排序.

就是问逆序对数量,树状数组就成$QwQ$

[X]货车运输

考虑先求一棵最大生成树,然后现在就变成了求两点之间路径上的最短边.

倍增下就成$QwQ$

[X]积木大赛

$QwQ$可以看上面铺设道路,

[X]花匠

脑子不够数据结构来凑.

考虑设$f_{i}$表示考虑到第$i$个的$max$,线段树优化$dp$应该是可过的$QwQ$

$over$

讲个$NOIp$点儿的解法$QwQ$.

考虑分别维护两个条件的$min$和$max$.然后每次读入一个数,如果它需要大于$min$且大于$min$,就$ans++$,并把$max$更新成这个值,否则就给$min$更新下,取原值和当前值的最小值.

正确性显然?其实可以类似最长上升子序列的理解,最长上升子序列是考虑改变$dp$的意义,将$f_i$的意义改为长度为$i$时的$min$嘛.这里类似,将$f_i$的意义改为长度为$i$时的$min/max$就完事$QwQ$.

$over$

[X]华容道

 考虑每次游戏的步骤可以分为两个部分,一个是空白格子移动到起始位置旁边,一个是起始位置移动到目标位置.

然后先考虑起始位置移动到目标位置这个事儿,发现每次有两种决策,一种是把指定节点和空白格子交换位置,一个是空白格子从指定节点的一侧移动到另一次.

考虑将(指定节点位置,空白格子在指定节点的方向)作为状态,然后这两个决策就变成了两种连边方式,发现跑最短路就成.

然后现在就只要解决空白格子移动到起始位置旁边这个问题?直接$bfs$就完事$QwQ$

注意特判,$SX=TX,SY=TY$的情况,,,不然就可以成功获得$65pts$的好成绩$/kel$

$2012(6/6$

[X]Vigenère 密码

大模拟就完事$QwQ$

注意是已知密文求明文$QwQ$

[X]国王游戏

贪心+高精.

瞎写下这个贪心趴$QwQ$

显然考虑微扰法,考虑交换两个元素,首先对在他们前面的显然麻油影响,然后对在他们后面的,因为是左手乘积所以依然没影响.

发现只会影响这两个元素,于是分别计算下这两个元素交换顺序之后的贡献鸭$QwQ$.

为了表示方便,设前面的所有左手乘积为$A$.于是现在就变成比较$max{frac{A}{b_1},frac{Acdot a_1}{b_2}},max{frac{A}{b_2},frac{Acdot a_2}{b_1}}$的大小.

发现一个显然的是$frac{A}{b_1}<frac{Acdot a_2}{b_1},frac{A}{b_2}<frac{Acdot a_1}{b_2}$

所以现在就只要比较$frac{Acdot a_2}{b_1},frac{Acdot a_1}{b_2}$

所以按$acdot b$排序就完事$QwQ$.

[X]开车旅行

考虑倍增.

先预处理出每个点的第一近&第二近城市,然后搞下倍增.

回答询问就也倍增的类似$lca$询问地搞下就完事$QwQ$.

唯一要注意的就是当区间大小变为$1$的时候开车的人会改变,所以可以写成递归函数的形式这样改变开车的人就会简单些$QwQ$

$over$

[X]同余方程

$QwQ$考了三四次了我写题解都写烦了,,,$ex\_gcd$就完事.

[X]借教室

显然线段树就完事鸭,,,每个节点代表一天,然后记录下区间$min$,当整个的$min<0$的时候就$GG$了,$over$

[X]疫情控制

贪心,感觉也看过几次了$QwQ$

首先二分一个最短时间.

考虑先给每个点尽量向上跑,如果跑不到根节点就停最高能到达的点,否则就去根节点,记录下所有能到达根节点的队伍还能跑的时间和从那个子节点来的.

然后对所有能到达根节点的队伍按能跑的时间从小到大排序,每次去匹配能到达的最远的子节点.但是要特判下就如果当前队伍来自的那个子节点当前队伍无法到达,就优先去那个子节点.原因显然不说了$QwQ$

$over$

$2011(6/6$

[X]铺地毯

倒序扫一遍找到第一个覆盖这个点的地毯就完事.

[X]选择客栈

$QwQ$之前考爆零了,,,

说下$O(n)$做法,考虑对每个颜色记录最后一个消费小于等于等于$p$的客栈及之前有多少个客栈和共有多少个客栈

$O(n)$扫一遍一直更新这个信息顺便统计下就完事$QwQ$

[X]$Mayan$游戏

爆搜就成,注意每次$swap$之后一定要$update$鸭,$QwQ$

 

#include<bits/stdc++.h>
using namespace std;
#define rp(i,x,y) for(int i=x;i<=y;++i)

const int N=15;
int n;
struct as{int x,y,op;};
vector<as>V;
struct node
{
    int h[N],a[N][N];bool f[N][N],flg;
    bool jud(){return !(h[1]+h[2]+h[3]+h[4]+h[5]);}
    void upd(){rp(i,1,5){h[i]=0;rp(j,1,7)if(a[i][j])a[i][++h[i]]=a[i][j];rp(j,h[i]+1,7)a[i][j]=0;}}
    bool clr()
    {
        memset(f,0,sizeof(f));flg=0;
        rp(i,1,5)rp(j,1,7)
        {
            if(a[i][j] && !(a[i+1][j]^a[i][j]) && !(a[i+2][j]^a[i][j]))
                flg=f[i][j]=f[i+1][j]=f[i+2][j]=1;
            if(a[i][j] && !(a[i][j+1]^a[i][j]) && !(a[i][j+2]^a[i][j]))
                flg=f[i][j]=f[i][j+1]=f[i][j+2]=1;
        }
        rp(i,1,5)rp(j,1,7)if(f[i][j])a[i][j]=0;
        return flg;
    }
    void print(){printf("
");rp(i,1,5){rp(j,1,h[i])printf("%d ",a[i][j]);printf("
");}}
};
node t;

void dfs(node nw,int stp)
{
    if(nw.jud()){if(stp^n)return;rp(i,0,n-1)printf("%d %d %d
",V[i].x-1,V[i].y-1,V[i].op);exit(0);}if(!(n^stp))return;
    rp(i,1,5)
        rp(j,1,nw.h[i])
        {
            if(i<5 && nw.a[i][j]^nw.a[i+1][j])
            {node tmp=nw;swap(tmp.a[i][j],tmp.a[i+1][j]);tmp.upd();while(tmp.clr())tmp.upd();V.push_back((as){i,j,1});dfs(tmp,stp+1);V.pop_back();}
            if(i^1 && !nw.a[i-1][j])
            {node tmp=nw;swap(tmp.a[i][j],tmp.a[i-1][j]);tmp.upd();while(tmp.clr())tmp.upd();V.push_back((as){i,j,-1});dfs(tmp,stp+1);V.pop_back();}
        }
}

int main()
{scanf("%d",&n);rp(i,1,5){int x;scanf("%d",&x);while(x)t.a[i][++t.h[i]]=x,scanf("%d",&x);}dfs(t,0);printf("-1
");return 0;}
View Code

 

[X]计算系数

考虑如果$a=1,b=1$,答案就$C(k,n)$.然后现在$a,b$不保证等于$0$,想下$a,b$的贡献,不难想到答案就$C(k,n)cdot a^ncdot b^m$

$over$

[X]聪明的质监员

二分,$cjk$学长讲过$QwQ$

然而题目给的公式很奇葩我先解释下,意思是说设所有$w_i>=W$的数量为$x$,所有$w_i>=W$的$v_i$之和为$y$,贡献就$xcdot y$

然后直接二分就完事.

[X]观光公交

考虑贪心.

为了表达方便,设$S_i$表示站点$i$的到达时间,$T_i$表示站点$i$的所有乘客到达的时间.

首先$S_i>T_i$就没有加速的意义了.否则找到能影响的人数最多的路径(倒序做后缀和,当$S_i>T_i$的时候清零就完事$QwQ$,然后加速

复杂度是$O(nk)$的$QwQ$(其实优化到$O(n^2)$还是蛮简单的,,,?就每次对一条路径撸到尽头就完事$QwQ$.

$over$

$2010(4/4$

[X]机器翻译

模拟就完事,,,我我我我开始看错题了以为是可以消去任意一个

(所以可以消去任意一个咋做啊$kk$

(好像我印象中$APIO$讲课的时候讲了个类似的问题,,,?忘了$/kk$

[X]乌龟棋

$dp$经典题了,,,考虑设$f_{i,j,p,q}$啥的分别记录每张牌的剩余数量的时候的最大收益.$over$

[X]关押罪犯

并茶几经典题$QwQ$

先按仇恨值从大到小排序,一直做直到不满足为止,$over$

[X]引水入城

先$bfs$处理出底下每个城市有哪一段可以覆盖它.

然后贪心就成$QwQ$

$2009(4/4$

[X]潜伏者

模拟就完事.

[X]$Hankson$的趣味题

考虑质因数分解之后$gcd$和$lcm$的意义就质数的$min$和$max$.

所以分别质因数分解之后就能知道$x$的指数范围,就能得到若干个大于小于等于的大小关系.

无解就相当于存在$l>r$或等于两个不相等的数.否则答案就$prod (r_i-l_i+1)$

注意几个细节.

第一个是在质因数分解的时候记得最后判下是否有大于$sqrt n$的质因数.

第二个是,可能是我实现丑的原因,我是直接$l_i$存关于$i$的限制.就要开$map$,因为要意识到有$sqrt n$的质因数$QwQ$.

然后想清楚了再打代码,,,我居然$WA$了两三发,$NOIp$必将惨败了$/kk$

[X]最优贸易

先考虑一个$O(n^2)$的做法,就从每个点出发$bfs$更新它能到达的所有城市的购买价钱,最后$O(n)$扫一遍取$max$就完事.

但是这个复杂度显然不可,考虑优化.

发现如果从小到大排序之后每次就只有没有被访问过的点可以被扩展.

原因显然?就如果被访问过了则这个点所有能访问的点就也都被访问了所以这个点就没有意义了.

所以每个点都只会被扫一遍,就变成$O(n)$的了.

注意可行点必须与起点或终点联通,因为不保证联通所以要处理下$QwQ$

[X]靶形数独

爆搜就完事,也没啥优化,$over$

然后我印象中好像从后往前搜比从前往后搜快些,,,?别问问就爆搜玄学卡常$QwQ$

$2008(4/4$

[X]双栈排序

一道神仙题,,,开始看完全不会,,,所以虽然写了题解但我还是重新说下,只是比较简略.梳理下思路而已.

先考虑什么情况下就不能放一个栈中,当且仅当.$p_k<p_i<p_j,i<j<k$.所以先预处理一个后缀$min$,然后就能$O(n^2)$处理出不能共存的点对.

然后就二分图染色?因为优先级所以尽量把前面的放到第一个栈中.

分配完之后就能输出方案了.细节不说了可以去看我题解$QwQ$

[X]火柴棒等式

先预处理一个每个数字要用多少个火柴棒,然后枚举两个加数$check$就完事.

[X]笨小猴

直接做就完事,没啥好说的,,,$QwQ$

[X]传纸条

$dp$经典题了,,,

首先去一次回一次可以当作去两次,设$f_{i,j,p,q}$表示分别在$(i,j),(p,q)$,一个优化是因为$i+j=p+q$所以可以减一维

$over$

$2007(3/4$

[X]矩阵取数游戏

首先显然的是每行互相独立可以分别做.

然后考虑设$f_{l,r}$表示$[l,r]$的最大得分,$O(n^2)$转移就成

然后因为是$2^{80}$又不取膜所以显然要高精

$code$(其实$int128$可过?但是$NOIp$似乎不能用我就写的高精$QwQ$

[X]统计数字

桶排,$over$

[X]字符串的展开

模拟就完事,$over$

[ ]树网的核

发现$n$贼小,可以直接做

于是找出直径然后直接枚举一个端点,取$s$的长度,算下那个值就完事.这个就$O(n^2)$的是趴.

(这题有个变式,数据范围$++$了:这里!

我一块儿讲了趴$QwQ$

考虑找出直径之后对直径上的每个点$x$求出$dis_x$表示点$x$不经过直径上其他点能到达的最远距离.因为限制了不经过直径上其他点所以是$O(n)$的

然后答案就$max{dis_{a_i},dis_{a_{i+1}},...,dis_{a_j}}$,其中$len_{i,j}leq s$且$len_{i-1,j}>s$

这不就一个单调队列就$O(n)$做掉了嘛$QwQ$

$2006(2/4$

[X]能量项链

一个很经典的区间$dp$.

首先断环为链不说,然后设$f_{i,j}$表示区间$[l,r]$的最大贡献,枚举$kin [l,r]$就成.

[X]金明的预算方案

一个很经典的有依赖性背包.

把主件和附件绑定当作一个新的物体背包就成

但是因为每个只能选一次所以不能真的分开做,要在决策主件的时候顺便把和附件绑定的一块做了,这样就能保证每个主件最多选一次了$QwQ$

[X]作业调度方案

难点在于看懂题$/dk$

看懂题就是一道模拟题了,$over$

 

#include<bits/stdc++.h>
using namespace std;
#define rp(i,x,y) for(int i=x;i<=y;++i)

const int N=30,M=40000+10;
int m,n,ord[N*N],mac[N][N],tim[N][N],cnt[N],pre[N],as;
bool timmac[N][M];

int main()
{
    //freopen("1065.in","r",stdin);
    scanf("%d%d",&m,&n);rp(i,1,n*m)scanf("%d",&ord[i]);rp(i,1,n)rp(j,1,m)scanf("%d",&mac[i][j]);rp(i,1,n)rp(j,1,m)scanf("%d",&tim[i][j]);
    rp(i,1,n*m)
    {
        int nw=ord[i],num=++cnt[nw],mach=mac[nw][num],t=tim[nw][num];
        int j=pre[nw]+1,ret=0;while(ret<t)if(!timmac[mach][j])++ret,++j;else ret=0,++j;
        --j;pre[nw]=j;as=max(as,j);while(ret)timmac[mach][j]=1,--ret,--j;
    }
    printf("%d
",as);
    return 0;
}
View Code

 

[ ]$2^k$进制数

,,,又没看懂题,$wzbl$

$2005(4/4$

[X]谁拿了最多奖学金

大模拟,#论$swich$的正确使用.

[X]过河

要先看懂题目大意鸭$QwQ$

就,不是一定要踩在石子上的$QwQ$

不难想到设$f_i$表示坐标为$i$的时候踩到最小石子数量.发现$L$太大了,空间开不下然后时间也不对.

但是不难发现因为石子数量很少,所以一定有很多段是空荡荡的

首先对于$p,p+1$,当$p ot=1$的时候有$gcd(p,p+1)=1$,由$NOIp2017$小凯的疑惑可知在$pcdot (p+1)-p-(p+1)$之后的点一定都能被$p,p+1$表示出来,即$pcdot (p-1)$及之后的点都能被到达.

也就说如果一个石头后面$72$个距离之后依然没有石头,那么就可以把后面那一段全部缩掉,因为后面那一段和$72$个距离那个位置是等价的.

然后说下上面讨论的情况忽略了的特殊数据点.

就存在$s=t$的情况,此时就不存在两个点$p,p+1$了.但是发现能跳的距离只有一个辣,直接看哪些石头会被跳到就完事$QwQ$

$code$

[X]篝火晚会

首先如果有$x$希望$y$在旁边$y$不希望$x$在身边就无解了.

现在考虑如果钦定了一个位置排列,怎么算最少的总代价?

一个显然的是一定可以每次只移动错误的且每次操作的错误的在操作了一次之后就会被放到正确的位置上去.正确性很显然的亚子$QwQ$?

然后现在就变成找一个合适的位置排列使得错误的位置最少了.发现固定两个点之后整个排列就被确定下来了,所以总共就$2n$个排列.

发现这时候复杂度是$O(n^2)$的,依然过不去

继续考虑优化.发现本质上只有$2$个排列,只是因为断环为链所以有$2n$个.

现在考虑先随便做一个目标排列,然后做差值算出每个点要移动多少次能和目标对齐.发现每次移动之后只有目标移动次数等于当前移动次数的点能匹配,其他的都布星,现在是要不匹配的点最少,就要匹配的点最多.也就说找到移动值相等的最多点数的这个点的数量$x$,答案就$n-x$

$code$

(我好像,倒数第二段讲得语言有点罗嗦,,,不过反正应该也没人看是趴$QwQQQQQQ$.

(如果有人看了没看懂在评论区问就是了$QwQQQQQQQQ$

(嗷对了记得正反各做一遍鸭因为本质是有两个排列的$QwQQQQQ$

($05$年的题好神啊,,,我要是没做过$CSP$遇到就直接惨败了$/ll$

$QwQ$因为被两个人$D$说写得看不懂了所以我来再港下,,,虽然大概还是看不懂$QwQ$

首先$O(n^2)$应该都能懂,,,?然后前面那个答案=不匹配数的结论应该都懂?所以现在就是要构造一个排列在满足那个同学的要求的同时让匹配的数量最多.

n^2就是,本来满足要求的排列是个环,我枚举从哪里断环为链是趴

考虑现在构造两个环,内层是1-n的顺序,外层是满足要求的序列.

因为形成的是环所以外层是唯一的了(其实是两个,为了方便讨论这里先看作一个,另一个之后一样的方法做一次就完事.

现在考虑断环为链的实质,其实就是内层不变,外层在旋转

然后$O(n)$枚举每个点,对每个点$O(1)$地算出外层旋转几个格子能和它匹配.

然后$O(n)$地枚举旋转几个格子,因为前面已经算出来了,在前面用桶记录下就可以知道旋转这么多格子有多少个格子是能匹配的了

然后对能匹配数取$max$,答案就$n-$能匹配数,正反各做一遍就完事.

$over$

[X]等价表达式

$05$年的$NOIp$好可怕啊,,,两道思维题和一道蛇皮大模拟我要碰到就直接$GG$了啊$/ll$

首先一个显然的是直接做显然不可做,,,

考虑可以多带几个$a$,如果都相等就是相等的了$QwQ$

一个坑点是括号可能不匹配,可以提前判掉不匹配就直接$GG$

因为读入很坑所以放下$code$(不要在本机测鸭至少我在本机$emacs$上跑连读入都不对,,,我我我我这题全程是在$luoguIDE$上调的$QwQ$

$2004(4/4$

[X]津津的储蓄计划

模拟,$over$

[X]合并果子

因为没有要求必须合并相邻的所以每次选最小的两堆就完事.

[X]合唱队形

发现要删去尽量少也就留下尽量多,正着反着分别求一遍最长上升子序列就完事.

可以优化成$nlogn$,应该都会我不说了$QwQ$

[X]虫食算

$QwQ$寒假还考过.

正解是高斯消元但是太麻烦了我只说爆搜辣$QwQ$

先预处理出所有未知数,然后一个个搜.

两个剪枝

一个是最高位不能有进位

还一个是如果某一位三个数都确定了而且$a+b ot=c,a+b+1 ot=c$就显然$GG$

没了.

$2003(3/4$

[X]神经网络

做这题的关键在于看懂题.

如果有$60pts,WA$在$#3 #5$或$80pts,WA$在$#3$的可以来问我,,,我我我我$WA$了半天才发现这个辣鸡题目成功让我理解错题目错了两次:D

[ ]侦探推理

呕,这题真的绝恶心,比时间复杂度还恶心,我永远讨厌大模拟:)

反正我是,到现在还没调出来

坑贼多

太恶心了我其他题还没做完之前不会碰这题了:)

[X]加分二叉树

,,,$03$年的题有病病嘛???

一道语文题一道大模拟一道隐含条件题真的瑞斯拜了,,,

就,这题有个隐含条件是说前序遍历输出要求字典序最小,,,$QwQ$

然后就$easy$了鸭?考虑设$f_{i,j}$表示$[i,j]$为一棵子树的最大得分.

转移就枚举根$kin [i,j],f_{i,j}=max{f_{i,k-1}cdot f_{k+1,j}+val_k}$

感觉有点像,二叉查找树那题$QwQ$?($ummm$大概是简单很多版$QwQ$

[X]传染病控制

长得就很贪心的样子,,,

然而并不是贪心$QwQ$

考虑$dfs$.

首先一个很显然的是每次传染病都只会传染一层.

所以只要一层层地搜看切断哪个就完事.

记得每次切断之后要把整棵子树标记掉,因为是一层层搜的,就可能出现在上面已经断开一次了之后又在子树内断了一次还把贡献加上了的情况$QwQ$

然后可以加个最优性剪枝?当前传染病人数$geq ans$的时候直接$return$了$QwQ$

不会算复杂度,虽然感觉会$T$的亚子但反正数据水也能水过去$QwQ$

$2002(4/4$

[X]均分纸牌

贪心经典题,从一端一直做下去就完事.

[X]字串变换

长得就很迭代加深鸭,,,

正好很久没写迭代加深了我就写迭代加深顺便复习下趴$QwQ$.

做法不难$get$趴?就设置一个深度$lim$,当次数$>lim$就直接不做了.

出于某不知名原因我代码中有个$char$数组不清零就会出现玄学错误,,,$QAQQQQQ$

然后和$wzf$小朋友交流一下之后发现可以写哈希我呆了没想到,,,$QAQ$

嗷然后还一种是双向$bfs$.一个预警:我我我我我就不写代码了,下面都是瞎胡的正确性都没有保障.

双向$bfs$就贼简单?从两边分别$bfs$,开两个$queue$分别存下来,然后当一个状态被两边都搜到就有解了$QwQ$

因为限制了$10$层双向$bfs$层数减半所以状态数大大减小$QwQ$.

好像也很久没写双向$bfs$了我可能还是会写下代码的趴$QwQ$不想写辣,,,等全落实完再说趴$/kk$

[X]自由落体

$QwQ$安利一个全网最呆想法,,,

直接$O(n)$枚举点,然后算出横坐标和车有交集的时间范围$[t_1,t_2]$,然后就能算出此时求的高度范围$[h_1,h_2]$

然后判下高度范围和车高有没有交集就完事$QwQ$

注意下题目里说了误差范围在$1e-4$以内就没事,,,我开始设成了$1e-8$然后$WA$了$#2$,,,$QAQ$($QwQ$,其实我想了下感觉可能不是误差范围的问题,,,?就是精度有问题,我这个误差判断其实依然是有问题的只是数据水就水过去辣$QwQ$

[X]矩形覆盖

$YY$了一个很呆的想法:爆搜这$K$个矩形的左下端点和右上端点

复杂度就$C(n,2cdot K-1)$(左下必须要选这个是显然的$QwQ$

$dbq$这个想法锅了,,,我才意识到可能端点不在这$n$个点上,,,我是呆呆$/dk$

依然考虑爆搜,考虑搜点,每次枚举这个点丢到哪个矩形,然后剪枝就判下矩形是否相交就完事.加个最优性剪枝应该是能过的毕竟是$NOIp$的数据,,,?

然后说下正确性,因为这个做法实际上是不能保证一定刚好$K$个矩形的,但是发现如果选的矩形数量少于$K$的数量,随意选一个包含点数大于等于$2$的矩形,一定存在一种方法能将这个矩形拆成两个小矩形且是合法的.

嗷然后枚举丢矩形的时候发现可能丢到很多次空矩形但本质是一样的,可以用类似愤怒的小鸟的搜索方法?就每次先$dfs$丢到非空矩形,再$dfs$扩展一个新矩形就成,就不会做很多次一样的了$QwQ$

$over$

$2001(6/6$

[X]一元三次方程求解

因为保证两个根的绝对值之差大于$1$,所以可以以$1$为单位计算这一段的解.

$over$

[X]数的划分

我好呆,我没看到那个$K$的限制我以为就一个完全背包就完事,,,

可以$dp$,然后因为数据范围贼小所以爆搜也过得去

$over$

[X]统计单词个数

考虑设$f_{i,j}$表示划分到$i$分成$j$份的方案数.转移就$f_{i,j}=max{f_{k,j-1}+cal(k+1,i)}$就成.

现在就只要考虑怎么算$cal(k+1,i)$就成.考虑再处理一个$g_{i,j}$表示$[i,j]$能否被一个字串表示出来,这个可以哈希$O(n^2cdot s)$地求.

然后再处理一个$num_{i,j}=cal(i,j)$,每次转移就$num_{i,j}=num_{i,j-1}+sum_{k=i}^j g_{k,j}$

嗷这里可能会有疑问鸭,就说可能存在某个$l$能匹配上两个字符串不久$GG$了嘛.

所以这里在处理$g$的时候注意点儿技巧,就当$g_{i,j}=1$的时候,就可以直接跳出$j$那一层循环了.

$over$

[X]$car$的旅行路线

题目有点恶心,,,我不太懂只给三个点的意义在于什么,,,就很无聊除了加大码量基本上没有啥意义了$/kk$

反正就,根据那三个点求出第四个点,建张完全图跑$dij$就成(其实应该跑$spfa$,,,?我印象中是说$spfa$在稠密图中比$dij$优秀来着$QwQ$?但是我我我我比较喜欢打$dij$所以就打了个$dij$

反正$NOIp$数据水是趴,能过就完事.

[X]挖地雷

设$f_i$表示挖到点$i$能挖多少个地雷

瞎转移下就完事.$QwQ$

输出方案瞎搞下就做完辣$QwQ$

[X]砝码称重

多重背包经典题

优化都不要的那种.

$over$

(我,单调队列优化背包,还是有点懵,,,$mk$着这几天要落实下$/kk$

$2000(4/4$

[X]方格取数

好像,和,传纸条没啥区别,,,?

$over$

[X]进制转换

首先没有负数就随便做是趴$QwQ$.

现在考虑负数,发现其实差不多,只是当出现的是负数的时候要加一个$base$

一直做下去就成.

[X]乘积最大

直接$dp$,设$f_{i}$表示在$i$后面有一个乘号的最大方案.

发现要写高精,还是高精乘.其实也不难,模拟下乘法的过程就行.

[X]单词接龙

$QwQ$这题我会的方法复杂度是假的,,,

只是$NOIp$日常数据水能过去而已,,,

我也不知道,有没有啥复杂度是对的的做法$QwQ$?反正我不会就完事$/kk$

我做法就贼简单啊,直接爆搜,注意下细节就它说每个单词能用两次,$QwQ$

嗷然后关于他那个啥包含关系的那个其实就是个废话,,,你发现包含关系这个显然是不优的,,,$over$

$1999(2/2$

[X]旅行家的预算

开始感觉长得很像$POJ2431$,但是发现那题正好相反,是油箱油量无限加油站油量有限$QAQ$

考虑类似思想,维护一个单调队列,记录一路过来加油站能多加的油,保证加油站坐标递增油价递增.

每次到了当前加油站之后,先弹队头直到油量可以资瓷从上一加油站到这个加油站.

然后再弹队尾直到油价小于等于当前油价,中间资瓷下反悔操作

(即本来是在每个加油站都强制加满油,然后如果是从比我劣的地方过来的我就不加多加的那一段因为不优$QwQ$.这是充分性

(多加的那一段显然是不会对资瓷到达之前的某个加油站造成贡献的因为如果造成贡献就已经被pop_back了.这是必要性.

(充要性得证,故正确$QwQ$

然后把这个回收站的加满油的时候多加的油量$C-t$和$P_i$加入堆中就完事.$QwQ$

($t$是原本油箱中有的油,因为油量限制所以只能加$C-t$

我$jio$得这题还蛮妙的,,,放个$code$趴.

[X]邮票面值设计

我感觉,$99$年的题,都好神鸭$bushi$

考虑$dfs+dp$,先爆搜选什么数,同时$dp$下当前能表示出来的数的$max$.这个$dp$还是蛮简单的?设$f_i$表示面值$i$至少由多少张邮票表示出来,因为邮票的数量没有限制只是总数有限制所以这么做是对的嘛$QwQ$

然后就做完了

$QwQ$其实不是正解但是数据水也能水过去嘛是趴$QwQ$

$1998(2/3$

[X]车站

设第$i$站上车人数为$s_i$,下车人数为$t_i$,发现从第$3$站开始每一站$i$增加的人数就是$s_{i-2}$.

然后这个$s_i$显然是个斐波拉契的形式.设第二站上车下车人数为$d$,发现最后$m$是可以表示为.

$a+0+a+d+(a+d)+(a+2d)+(2a+3d)+...$

考虑先把$a$的贡献算出来减掉,然后$d$的系数和很容易求出来,就能算出$d$了,算出$d$之后再递推次就能知道第$x$站有多少人了$QwQ$

[X]拼数

考虑给字符串排序之后直接按顺序连接着输出就完事.

现在只要考虑怎么排序了.

首先如果有一位的值不同显然把大的放前面.

然后如果较短的都扫完了依然相同,就比较较长串后一位和第一个位置字母的大小,哪个大哪个放前面就成.

($upd:$发现我是憨憨,,,可以直接用字符串加法比较$a+b$和$b+a$的大小,,,完全不需要自己写啊喂,,,$QAQQQQQ$

[ ]进制位

,,,看不懂题我跑路了$/dk$

$1997(1/1.5$

[X]棋盘问题

考虑先对每个数$i$预处理一个$vector$存哪些数可以接在$i$的邻侧.

然后就爆搜,先搜出第一行第一列,最优性剪枝下,然后再爆搜$check$是否可行就成.

$over$

[ ]棋盘问题[加强](听$wzf$小朋友说数据有锅$QwQ?$

原文地址:https://www.cnblogs.com/lqsukida/p/11623888.html