前言
还是第一道签到题没有做出来,但是感觉这一次的考试还不错,不过还是可以发现问题,其实就是对于已经学过的东西记忆十分不好,所以在清明节的时候我打算回顾一下已经学过的代码
第一题
这其实是一道萌萌题,显然假如一个串的长度为i,i>k ,那么假如前面k个都可以整除2^k,那么这个串必然也可以整除,这是因为(10的k次方可以被2的k次方整除,这个也比较好理解),所以只用就去对于每一个i,只用去看每一个前k为的串是不是满足被2的k次方整除,之后合并就欧克,复杂度估计是nk,符合要求
int main(){
//一堆输入
int fl=(1<<k)-1;//减1是为了方便取模
for(int i=1;i<=20;i++) fw[i]=(fw[i-1]*10)&10;//提前做2的k次方就和10的k次方的取模
for(int i=1;i<=n;i++){
if(i-k>1) {
if(a[i-k]!=0)tot++;//统计一共有几个超过k的,并去掉前导零
}
for(int j=0;j<k&&i-j>=1;j++){
num=(num+pw[j]*a[i-j])&fl;
if(a[i-j]==0&&j!=0) continue;//去掉前导零
if(num==0) ans++;
}
if(num==0) ans+=tot;//这就是加上前面有几个需要看的
if(a[i]==0&&k==0) ans++;//做特殊的情况
}
cout<<ans;
}
第二题
这就是一个dp的小题目,设计状态dp[i][j] 表示第 i 次转移跳到 j 所需要的最小代价,所以说显然转移方程为,假如第 i 次的操作是从 u 和 v 那么dp[i][v] = min(dp[i-1][v]+1,dp[i-1][u]),dp[i][u] = min(dp[i-1][u]+1,dp[i-1][v])。 最后就是简简单单的初始化的操作,显然dp[0][…]=INF,每一个最开始都需要进行很多次的安县操作,这样才可以保证这个的正确性,最后第一维可以用滚动数组来滚掉就好了。
主要就是看到这种最小值的问题还是想一想dp吧,想我在考试想到的建图显然是不可能的。