zoukankan      html  css  js  c++  java
  • NOIP模拟测试25「字符串·乌鸦喝水·所陀门王的宝藏(陀螺王)」

    字符串

    题解

    没看出catalan怎么办

    dp打表啊!

    考虑大力dp拿到30分好成绩!顺便收获一张表

    打表发现$C_{n+m}^{m}-C_{n+m}^{m-1}$

    仔细观察然后发现其实就是之前的网格那个题

    那么我们回顾一下网格那个题

    先看最简单的n==m情况

    求左下角走到右上角方案数,不能经过中间那条线

    考虑大力容斥,首先总方案数$C_{2*n}^{n}$很好求,那么我们现在任务就是求不合法的

     我们考虑到如果经过中间那条线我们至少要经过红色那条线,考虑求从左下角超过那条蓝线(不合法)方案数,

    如果有红线限制我们好像仍然难以求出,我们怎么消除红线影响

    方法非常简单:考虑将正方形翻折,那么我们经过绿线走到右上角就转变为了沿绿线走再沿蓝线走方案,这样我们就摆脱了红线的控制

    那么我们就转化为了从左下角走到翻折后多边形所在角在位置

    得到$C_{(n+1)+(n-1)}^{n-1}$即$C_{2*n}^{n-1}$

    相减即可

    那么如果$n!=m$类似$C_{n+m}^{m}-C_{n+m}^{m-1}$,自己画画即可

    代码

    我不想放了

    乌鸦喝水

    题解

    $55分算法$

    先预处理出来能喝多少次

    $n*m$ 复杂度,

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1010101
    ll cishu,maxn,n,m,all=0;
    ll a[A],he[A],xiajiang[A];
    int main(){
        scanf("%lld%lld%lld",&n,&m,&maxn);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(ll i=1;i<=n;i++){
            scanf("%lld",&xiajiang[i]);
            he[i]=(maxn-a[i])/xiajiang[i];
        }
        for(ll i=1;i<=m;i++){
            all=1;
            for(ll j=1;j<=n;j++){
                if(he[j]>=cishu){
                    cishu++;
                    all=0;
                }
            }
            if(all) break;
        }
        printf("%lld
    ",cishu);
    }
    View Code

    $95分算法$

    我们重复枚举了很多无用的状态,当前已经喝不到我们不用再考虑,于是拿链表优化一下

    $100分算法$

    这种题肯定有性质,这么大的范围一定有性质.

    性质: 水少的喝了$k$次那么水多的一定至少也喝了$k$次

    我们考虑排序,然而排序后打乱了顺序怎么办,拿一个树状数组维护一下排序前的

    我们可以快速算出在当前水壶喝了多少水

    思考已知之前喝了$ans$次当前还剩$w$个水壶没喝完,这个水壶能喝$cnt$次

    那么它能喝$frac{cnt-ans}{w}$轮

    考虑喝完这么多轮会有剩余,这时用树状数组找sum就完了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1111111
    ll c[A],xiajiang[A],he[A],a[A];
    ll n,m,maxn,ans=0;
    struct toot{
        ll pos,cnt;
        friend bool operator < (const toot &a,const toot &b){
            return ((a.cnt==b.cnt)?(a.pos<b.pos):(a.cnt<b.cnt));
        }
    }que[A];
    void add(ll l,ll a){
        for(ll i=l;i<=n;i+=(i&-i))
            c[i]+=a;
    }
    ll sum(ll l){
        ll sum=0;
        for(ll i=l;i>=1;i-=(i&-i))
            sum+=c[i];
        return sum;
    }
    int main(){
        scanf("%lld%lld%lld",&n,&m,&maxn);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(ll i=1;i<=n;i++){
            scanf("%lld",&xiajiang[i]);
            he[i]=(maxn-a[i])/xiajiang[i]+1;
            que[i].cnt=he[i],que[i].pos=i;
            add(i,1);
        }
        sort(que+1,que+n+1);
    //    printf("que[1]=%lld
    ",que[1].cnt);
        for(ll i=1;i<=n;i++){
            add(que[i].pos,-1);
            if(que[i].cnt<=0) continue;
            if(que[i].cnt-ans<=0) continue;
            ll cnt=(que[i].cnt-ans)/(n-i+1);
            if(cnt>=m){
                ans+=m;
                continue;
            }
            if(sum(que[i].pos)<((que[i].cnt-ans)%(n-i+1)))
                cnt++;
            ans+=cnt;
        }
        printf("%lld
    ",ans);
    }
    View Code

    所驼门王的宝藏(骆驼王)

    题解

    缩点跑一个类似最长链的东西

    数组大小比较谜

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll int
    #define A 2000010
    ll n,m,k,tot=0,cnt=0;
    ll id(ll x,ll y){
        return (x-1)*m+y;
    }
    inline ll read(){
        ll f=1,x=0;char c=getchar();
        while(!isdigit(c)){
            if(c=='-') f=-1;
            c=getchar();
        }
        while(isdigit(c)){
            x=(x<<1)+(x<<3)+(c-'0');
            c=getchar();
        }
        return f*x;
    }
    ll head[A],nxt[A<<1],ver[A<<1],a[521000],b[521000],c[521000],sz[A],dfn[A],low[A],sta[A],belong[A],f[A];
    ll head_[A],nxt_[A<<1],ver_[A<<1];
    map< pair<ll,ll>,ll > mp;
    ll top=0,toot=0,scc=0,tot_=0;
    bool flag[A],vis[A],ins[A];
    vector<ll> hang[A],lie[A];
    void add(ll x,ll y){
    //    printf("x=%d y=%d
    ",x,y);
        ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
    }
    void add2(ll x,ll y){
    //    printf("x=%d y=%d
    ",x,y);
        ver_[++tot_]=y;
        nxt_[tot_]=head_[x];
        head_[x]=tot_;
    }
    void tarjan(ll x){
        dfn[x]=low[x]=++toot;
        sta[++top]=x;
        ins[x]=1;
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(!dfn[y]){
                tarjan(y);
                low[x]=min(low[x],low[y]);
            }
            else if(ins[y]) 
                low[x]=min(low[x],dfn[y]);
        }
        if(low[x]==dfn[x]){
            ll y=0;
            scc++;
            while(1){
                y=sta[top--];
                belong[y]=scc;
                ins[y]=0;
                sz[scc]++;
                if(y==x) break;
            }
        }
    }
    ll dp(ll x,ll pre){
        if(f[x]) return f[x];
        f[x]=0;
        for(ll i=head_[x];i;i=nxt_[i]){
            ll y=ver_[i];
            ll nx=dp(y,x);
    //        printf("x=%d y=%d nx=%d
    ",x,y,nx);
            f[x]=max(f[x],nx);
        }
        f[x]+=sz[x];
        return f[x];
    }
    void rebuilt(){
        for(ll i=1;i<=k;i++){
            for(ll j=head[i];j;j=nxt[j]){
                ll y=ver[j];
                if(belong[i]!=belong[y]){
                    add2(belong[i],belong[y]);
                }
            }
        }
    }
    int main(){
        k=read(),n=read(),m=read();
        for(ll i=1;i<=k;i++){
            a[i]=read(),b[i]=read(),c[i]=read();
            mp[make_pair(a[i],b[i])]=i;
            hang[a[i]].push_back(i);
            lie[b[i]].push_back(i);
        }
        for(ll i=1;i<=k;i++){
            if(c[i]==1){
                for(ll j=0;j<hang[a[i]].size();j++){
                    if(i!=hang[a[i]][j])add(i,hang[a[i]][j]);
                }
            }
            if(c[i]==2){
                for(ll j=0;j<lie[b[i]].size();j++){
                    if(i!=lie[b[i]][j])add(i,lie[b[i]][j]);
                }
            }
            if(c[i]==3){
            ll _1_=mp[make_pair(a[i]-1,b[i])],_2_=mp[make_pair(a[i]+1,b[i])],_3_=mp[make_pair(a[i],b[i]+1)],_4_=mp[make_pair(a[i],b[i]-1)]
            ,_5_=mp[make_pair(a[i]+1,b[i]+1)],_6_=mp[make_pair(a[i]+1,b[i]-1)],_7_=mp[make_pair(a[i]-1,b[i]-1)],_8_=mp[make_pair(a[i]-1,b[i]+1)];
            if(_1_)    add(i,_1_);
            if(_2_)    add(i,_2_);
            if(_3_)    add(i,_3_);
            if(_4_)    add(i,_4_);
            if(_5_)    add(i,_5_);
            if(_6_)    add(i,_6_);
            if(_7_)    add(i,_7_);
            if(_8_)    add(i,_8_);
            }
        }
        for(ll i=1;i<=k;i++){
            if(!dfn[i])    tarjan(i);
        }
    //    for(ll i=1;i<=k;i++){
    //        printf("belong=%d
    ",belong[id(a[i],b[i])]);
    //    }
        rebuilt();
        for(ll i=1;i<=scc;i++){
            if(!f[i])
            dp(i,0);
        }    
        for(ll i=1;i<=scc;i++){
            f[0]=max(f[0],f[i]);
        }
        printf("%d
    ",f[0]);
    }
    View Code
  • 相关阅读:
    设计模式-Note9-行为变化类
    设计模式-Note8-数据结构类
    设计模式-Note7-状态变化类
    设计模式-Note6-接口隔离类
    设计模式--Note5--对象性能类
    设计模式--Note4--对象创建类
    设计模式--Note3--单一职责类
    设计模式--Note2--组件协作类
    V$ACCESS 查询结果慢的解决方法
    openstack numa详解(命令使用篇)
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11374102.html
Copyright © 2011-2022 走看看