zoukankan      html  css  js  c++  java
  • noip模拟测试21


    T1:折纸

      这道写崩我也是没话说……

      模拟就完了,记录每次的折叠点,每次将之前的都扫一遍就完了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstdlib>
     7 #define ll long long
     8 using namespace std;
     9 const int MAXM=50000;
    10 ll n,m,pos[MAXM],l,r;
    11 int main() {
    12     scanf("%lld%lld",&n,&m);
    13     l=0LL;r=n;
    14     for(int i=1,p;i<=m;i++) {
    15         scanf("%lld",&pos[i]);
    16         ll tmp=pos[i];
    17         for(int j=1;j<i;j++)
    18             if(pos[j]<tmp) tmp=2*pos[j]-tmp;
    19         pos[i]=tmp;
    20         l=min(l,2*tmp-r),r=tmp;
    21         if(l>r) swap(l,r);
    22     }
    23     printf("%lld
    ",r-l);
    24     return 0;
    25 }
    t1 Code


    T2:不等式

      推了一个多小时……

      $L leq S*x mod M leq R$

    → $L leq S*x - lfloor $$ frac {S*x} {M} $$ floor *M leq R$

    → $S*x - R leq lfloor $$ frac {S*x} {M} $$ floor *M leq S*x - L $

      这里是最关键的一步,同时模S

    → $-R mod S leq lfloor $$ frac {S*x} {M} $$ floor * M mod S leq -L mod S$

      到这里我们可以发现,式子变成了一个和原式形式相似的式子

      在该式中:$ M' = S qquad S' = M mod S qquad L' = -R mod S qquad R' = -L mod S $

      看到M和S的变化,很容易就会想到exgcd

      然后就像exgcd一样向下递归,当式子足够简单的时候计算答案或判断无解

      返回答案后再反推出本层x的值

      因为是exgcd的形式,只会递归$log$层,所以复杂度正确(虽然我并不会算……)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstdlib>
     7 #define ll long long
     8 using namespace std;
     9 int T;
    10 ll m,s,l,r,ans;
    11 bool flag;
    12 void solve(ll mm,ll ss,ll L,ll R,ll &x) {
    13     if(!L) return (void)(x=0);
    14     if(mm<=L||L>R||ss%mm==0) return (void)(x=-1);
    15     ll tmp=(L-1)/ss+1;
    16     if(tmp*ss<=R) return (void)(x=tmp);
    17     solve(ss,mm%ss,((-R)%ss+ss)%ss,((-L)%ss+ss)%ss,x);
    18     if(x==-1) return;
    19     tmp=(R+mm*x)/ss;
    20     if(ss*tmp-mm*x>=L) return (void)(x=(tmp%mm+mm)%mm);
    21     return (void)(x=-1);
    22 }
    23 int main() {
    24     scanf("%d
    ",&T);
    25     while(T--) {
    26         scanf("%lld%lld%lld%lld",&m,&s,&l,&r);
    27         solve(m,s,l,r>m?m-1:r,ans);
    28         printf("%lld
    ",ans);
    29     }
    30     return 0;
    31 }
    t2 Code


    T3:reverse

      恶心数位dp

      第一眼:“啊,数位dp!”

      第二眼:“怎么dp啊!”

      一个小时过去了……

      第三眼:“暴力,再见!”

      ……

      记忆化搜索

      设计状态$f[i][j][s_1][s_2]$表示考虑到第i位,填了j个数,这j个数reverse之后和l,r后j位的大小关系是$s_1和s_2$的个数

      但发现前导0很麻烦,看题解学到了一种新的处理方法,枚举数字长度,然后钦定第一位不为零

      注意:若当前数字位数小于r或l,在统计答案是需要特判其大小关系

      再注意:拆分l和r的数组需要清空!!!

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #define ull unsigned long long
    using namespace std;
    const int MAXN=22;
    int T,A,B,dig[MAXN],dl[MAXN],dr[MAXN],cl,cr;
    ull l,r,f[MAXN][MAXN][3][3];//0 < ;1 = ;2 > ;
    ull dfs(int pos,int revp,int cmpl,int cmpr,bool lim) {
        if(!pos) {
            if(revp-1<cl) cmpl=0;
            if(revp-1<cr) cmpr=0;
            return cmpl!=0&&cmpr!=2;
        }
        if(!lim&&f[pos][revp][cmpl][cmpr]!=-1) return f[pos][revp][cmpl][cmpr];
        int upr=lim?dig[pos]:9;
        ull ret=0;
        for(int i=0;i<=upr;i++) {
            int ncl,ncr;
            if(i==dl[revp]) ncl=cmpl;
            else ncl=i>dl[revp]?2:0;
            if(i==dr[revp]) ncr=cmpr;
            else ncr=i>dr[revp]?2:0;
            ret+=dfs(pos-1,revp+1,ncl,ncr,lim&&(i==upr));
        }
        if(!lim) f[pos][revp][cmpl][cmpr]=ret;
        return ret;
    }
    ull calc(ull x) {
        if(!x) return 0;
        memset(f,-1,sizeof(f));
        int cnt=0;
        for(ull tmp=x;tmp;tmp/=10) dig[++cnt]=tmp%10;
        ull ret=0;
        for(int i=cl;i<=cnt;i++) {
            int upr=i==cnt?dig[i]:9;
            for(int j=1;j<=upr;j++) {
                int ncl,ncr;
                if(j==dl[1]) ncl=1;
                else ncl=j>dl[1]?2:0;
                if(j==dr[1]) ncr=1;
                else ncr=j>dr[1]?2:0;
                ret+=dfs(i-1,2,ncl,ncr,i==cnt&&j==upr);
            }
        }
        return ret;
    }
    void clear() {
        cl=0;cr=0;l=0;r=0;
        memset(dig,0,sizeof(dig));
        memset(dl,0,sizeof(dl));
        memset(dr,0,sizeof(dr));
    }
    int main() {
        scanf("%d%d%d",&T,&A,&B);
        while(T--) {
            scanf("%llu%llu",&l,&r);
            for(ull tmp=l;tmp;tmp/=10) dl[++cl]=tmp%10;
            for(ull tmp=r;tmp;tmp/=10) dr[++cr]=tmp%10;
            printf("%llu
    ",calc(r)-calc(l-1));
            clear();
        }
        return 0;
    }
    t3 Code

    (多测不清空,爆零两行泪)


  • 相关阅读:
    createDocumentFragment 文档碎片提升dom增删的性能
    微信小程序引入外部js 方法
    javascript 阻止事件冒泡 cancelBubble
    javascript event事件兼容性处理
    SVN地址正确,能在网页打开,但是检出失败解决方法
    使用a标签下载文件,而不是直接打开,使用属性 download
    java 获取项目根目录
    ajax 提交所有表单内容及上传图片(文件),以及单独上传某个图片(文件)
    Vim命令图解和XVim使用
    解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题
  • 原文地址:https://www.cnblogs.com/Gkeng/p/11354607.html
Copyright © 2011-2022 走看看