noip模拟测试21

Posted gkeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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 $$ \rfloor *M \leq R$

→ $S*x - R \leq \lfloor $$ \frac S*x M $$ \rfloor *M \leq S*x - L $

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

→ $-R \ mod \ S \leq \lfloor $$ \frac S*x M $$ \rfloor * 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\n",&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\n",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\n",calc(r)-calc(l-1));
        clear();
    
    return 0;
t3 Code

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


 

以上是关于noip模拟测试21的主要内容,如果未能解决你的问题,请参考以下文章

2019.5.25 Noip模拟测试2

2019.5.18 Noip模拟测试

noip模拟测试9

noip模拟测试84

noip模拟测试11

2017.11.7~8模拟测试总结---暨NOIP2017考前对策