这次训练总结是10月29日到11月2日。
总体来说,做了数位DP一些稍微难一些的题目,也遇到了不。少。坑。(不到5道题,WR超过60发是什么感觉。。。)做了秦皇岛比赛的部分题目。下面很有必要写几道题的题解来提醒我注意细节的重要性。
1、HDU 3271
题意很简单,定义一个SNIBB数为B进制下各位数和等于给定数N。给定一个N,B,求给定区间内第K个SNIBB数或第1个,没有输出“Could not find the Number!”。
思路:数位DP模板+二分
但是这道题对我来说有很多坑,导致WR了20多发。。。还是细节不注意,写在这里提醒自己。
1、x!可!能!小!于!y!
2、求mid时会超出int范围!要先转换成long long...
3、小于等于0要特判。。。
4、不要偷懒!!!printf("Case %d:\n",cas++);刚开始我复制前一个题的代码改,结果后面多输出了个空格没注意,WR了20多发还一脸懵逼???!!!简直绝望。。。
5、这只是一道水题。但是细节细节细节必须注意!!!
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
2、ZOJ 3985
题意很简单,给你一个串,判断里面含多少个‘’CCPC‘’,还可以填一个‘P’或者“C”。
思路:刚开始想用KMP做,WR了将近20发,后来被告知是暴力。。。Orz
注意几个细节:
1、用过的字母还能用,但是下面找可以补成CCPC的时候就不能找之前就是完整的CCPC的。
2、三种可以补成CCPC的,就是CCC,CCP,CPC,后两种分别判断后面、前面有没有C,有的话刚才统计过了就不能用来补成CCPC,第一种CCC就不是直接判CCPC,而是判它下一位是不是P,是的话就不确定了,交给下一次的CCP判断,不是就可以补成CCPC,+1 break。(据说KMP也能做,但是我没做出来。。。)
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
3、HDU 3565
思路:数位DP。用7个数表示状态。
0:还没到第一个上坡
1:到了第一个上坡,不可以往下
2:第一个坡上,可以往下
3、正在下第一座山
4、踏上第二座山,不可以往下
5、在第二座山上,可以往下
6、第二座山的下坡,到这里就是两个峰了。
注意的细节:
这道题有几分玄学。。。用C语言过不了(不会C的64位。。。),而且它是有上下界的数位DP,开两个数组记录区间端点。
注意要用 unsigned long long!!!!!!刚开始没注意到又是蜜汁WR接近20次。
-1表示区间里没找到峰,输出0。否则直接输出结果。
C语言怎么就写不对呢???
AC代码:
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x7f7f7f7f
int f[40][10][7];
int sx[40],sy[40];
unsigned long long x,y,m,kk;
int max1(int a,int b){if(a>b) return a;return b;}
int dfs(int pos,int pre,int s,int fx,int fy) {
if(pos==-1) {return s==6?0:-1;}
if(!fx&&!fy&&f[pos][pre][s]!=INF) return f[pos][pre][s];
int min=fx?sx[pos]:0;
int max=fy?sy[pos]:9;
int ans=-1,i;
for(i=min;i<=max;i++) {
int ns=s;
if(s==0&&i) ns=1;
else if(s==1)
{if(i>pre) ns=2;
else ns=-1;
}
else if(s==2)
{if(i else if(i==pre) ns=-1;
}
else if(s==3&&i>=pre)
{ if(i) ns=4;
else ns=-1;
}
else if(s==4)
{if(i>pre) ns=5;
else ns=-1;
}
else if(s==5)
{if(i else if(i==pre)ns=-1;
}
else if(s==6&&i>=pre) {ns=-1;}
if(ns!=-1)
{
int sum1=dfs(pos-1,i,ns,fx&&i==min,fy&&i==max);
if(sum1!=-1) ans=max1(ans,i+sum1);
}
}
if(!fx&&!fy) f[pos][pre][s]=ans;
return ans;
}
int main() {
int t;
int cas=1;
memset(f,0x7f,sizeof(f));
while (cin>>t) {
while(t--)
{
cin>>x>>y;
cout<<"Case "<
int pos1=0;
for(;y;x/=10,y/=10)
{
sx[pos1]=x%10;sy[pos1++]=y%10;
}
int dd=dfs(pos1-1,0,0,1,1);
if(dd==-1) dd=0;
cout<
}
return 0;
}
这几天好几道题都栽在细节上了。今天在这里提醒自己以后一定要注意!!!一定要注意细节!!!(要不1A率怎么能那么低)
这几天功课比较繁重,但是依然不会放弃每天A题。。。
接下来几天再做几道有难度的数位DP,继续看我的数据结构,一定不能着急。。。功课要搞好!!!