2017年11月5日训练总结

这次训练总结是11月3日-11月5日。

总体来说,学会了数位DP+二分解决求第几个含哪些数字的数的问题,做了一些稍微难一些的题目。打了一场比赛,出了两道水题,一道是大数加法,一道是跳石头,简单模拟即可。对数位DP有了熟练地运用,一些简单题目应该可以很熟练快速的写出代码了。做秦皇岛赛区的比赛时,两个队友有事都没时间,于是一个人打。。。还算不错,出了三道,题目有乱码。。。有点难读,不过都是暴力题。第四道求多少个CCPC想用KMP做也没做出来,最后才知道是暴力,而在西安赛区的比赛题目里第六题貌似是打表,打好了却一直WR。。。有点懵。数位DP专题还剩下最后五道题,虽然之前看了大量的有关数位DP的博客,不过都是大同小异,基本都是些没难度的题,自己也划了一下水。一直只会递归这一种写法,虽然好理解,但是剩下的几道题貌似用递归就不好做了。。。还是得学一下dp常规写法的。今天做一道数位DP一血被抢了。。。差一个小时。。。有点气,不过这倒无所谓,重要的还是得学会,A了就好。另外,读题能力依然有待提高,像上一篇总结的问题--细节还是要加强重视和练习。

由于周六打一下午的比赛,周六凌晨的CF没打。。。这两天抽空做做。

努力做做剩下的几道数位DP,继续看我的字典树,在各大oj上找题刷,在bzoj上多刷几道题。。。千题计划仅完成了3%,要加快进度了...

菜,就要多努力。

贴一道经典的数位DP+二分代码,以后遇到这种题就要1分钟之内写出来。

题意:求第n个含666的数

代码:

#include
#include
#include
#include
#include
#include
using namespace std;
const long long INF=0x3f3f3f3f3f3f3f3fll;//long long 最大值 9223372036854775807
long long f[30][6];
int a[30];
int n,m;
int ind;
long long dfs(int pos,int s,bool limit) {
   if(pos==-1) return s==3;
   if(!limit&&f[pos][s]!=-1) return f[pos][s];
   int i,end=limit?a[pos]:9;
   long long ans=0;
    for(i=0; i<=end; i++) {
       int ns=s;
            if(s==2&&i==6) ns=3;
            else if(s==2&&i!=6) ns=0;
            else if(s==1&&i==6) ns=2;
            else if(s==1&&i!=6) ns=0;
            else if(s==0&&i==6) ns=1;
            ans+=dfs(pos-1,ns,limit&&i==end);
            }
        if(!limit) f[pos][s]=ans;
        return ans;
}
long long solve(long long xx){
    int pos=0;
    while(xx){
        a[pos++]=xx%10;
        xx/=10;
    }
    return dfs(pos-1,0,1);
}
long long go(long long n){
    long long fir=0,end=INF;
    long long ans=-1;
    while(fir<=end){
        long long mid=(fir+end)>>1;
        if(solve(mid)             fir=mid+1;
        }
        else{
            ans=mid;
            end=mid-1;
        }
    }
    return ans;
}
int main() {
    memset(f,-1,sizeof(f));
    int t;
    long long x,y;
    while (scanf("%d",&t)!=EOF) {
    while (t--){
        scanf("%lld",&x);
        printf("%lld\n",go(x));
    }
    }
    return 0;
}

你可能感兴趣的:(训练日记)