• NOIP模拟赛20161022


    NOIP模拟赛2016-10-22 

    题目名

    东风谷早苗

    西行寺幽幽子

    琪露诺

    上白泽慧音

    源文件

    robot.cpp/c/pas

    spring.cpp/c/pas

    iceroad.cpp/c/pas

    classroom.cpp/c/pas

    输入文件

    robot.in

    spring.in

    iceroad.in

    classroom.in

    输出文件

    robot.out

    spring.out

    iceroad.out

    classroom.out

    时间限制

    1000MS

    1000MS

    1000MS

    1000MS

    内存限制

    64MB

    128MB

    128MB

    128MB

    测试点

    20

    20

    10

    10

    测试点分值

    5

    5

    10

    10


    Problem 1

    东风谷早苗(robot.cpp/c/pas)

    题目描述

    在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女。某一天,早苗终于入手了最新款的钢达姆模型。作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧(好吧,我自重)。早苗的新模型可以按照输入的命令进行移动,命令包含’E’、’S’、’W’、’N’四种,分别对应四个不同的方向,依次为东、南、西、北。执行某个命令时,它会向着对应方向移动一个单位。作为新型机器人,自然不会只单单执行一个命令,它可以执行命令串。对于输入的命令串,每一秒它会按照命令行动一次。而执行完命令串最后一个命令后,会自动从头开始循环。在0时刻时早苗将钢达姆放置在了(0,0)的位置,并且输入了命令串。她想要知道T秒后钢达姆所在的位置坐标。

    输入格式

    第1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令

    第2行:一个正整数T

    输出格式

    第1行:两个整数,表示T秒时,钢达姆的坐标

    输入样例

    NSWWNSNEEWN

    12

    输出样例

    -1 3

    数据范围

    对于60%的数据:T <= 500,000且命令串长度 <= 5,000

    对于100%的数据:T <= 2,000,000,000且命令串长度<= 5,000

    注意

    向东移动,坐标改变改变为(X+1,Y);

    向南移动,坐标改变改变为(X,Y-1);

    向西移动,坐标改变改变为(X-1,Y);

    向北移动,坐标改变改变为(X,Y+1);


    很水的模拟  每一串命令位置变化是一样的

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=5005;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int t,n,sx=0,sy=0,x=0,y=0,dx[300],dy[300];
    char s[N];
    int main(int argc, const char * argv[]){
        freopen("robot.in","r",stdin);
        freopen("robot.out","w",stdout);
        scanf("%s%d",s+1,&t);
         dx['E']=1;dy['E']=0;
         dx['S']=0;dy['S']=-1;
         dx['W']=-1;dy['W']=0;
         dx['N']=0;dy['N']=1;
         n=strlen(s+1);
        for(int i=1;i<=n;i++){
            sx+=dx[s[i]];sy+=dy[s[i]];
        }
        int k=t/n,b=t%n;
        while(k--){x+=sx;y+=sy;}
        for(int i=1;i<=b;i++){
            x+=dx[s[i]];y+=dy[s[i]];
        }
        printf("%d %d",x,y);
    }



    Problem 2

    西行寺幽幽子(spring.cpp/c/pas)

    题目描述

    在幻想乡,西行寺幽幽子是以贪吃闻名的亡灵。不过幽幽子可不是只会吃,至少她还管理着亡灵界。话说在幽幽子居住的白玉楼有一颗常年不开花的樱树——西行妖。幽幽子决定去收集人间的春度,聚集起来让西行妖开花。很快,作为幽幽子家园艺师的魂魄妖梦收集到了M个单位的春度。并且在这段时间里,幽幽子计算出要让西行妖开出一朵花需要N个单位的春度。现在幽幽子想要知道,使用所有的春度,能够让西行妖开出多少朵花。

    输入格式

    第1行:一个正整数M

    第2行:一个正整数N

    N,M的位数不超过L,L的范围在题目后面给出

    输出格式

    第1行:一个整数ans,表示能开出花的朵数

    输入样例

    73861758

    12471

    输出样例

    5922

    数据范围

    对于60%的数据:L <= 2,000且ans <= 2,000

    对于100%的数据:L <= 20,000且ans <= 2,000,000,000


    高精度除法 二分答案来试探

    没用ll只有60分不开心,因为2e9+2e9还有*2e9都会溢出

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=2e4+5,INF=2e9;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct big{
        ll l,d[N];
        big(){l=1;}
    };
    char s[N];
    big a,b,c;
    bool check(big &a,big &b){//a>=b
        if(a.l>b.l) return 1;
        if(a.l<b.l) return 0;
        for(int i=a.l;i>=1;i--){
            if(a.d[i]>b.d[i]) return 1;
            if(a.d[i]<b.d[i]) return 0;
        }
        return 1;
    }
    //void jian(big &a,big &b){
    //    int g=0,l=b.l;
    //    for(int i=1;i<=l;i++){
    //        if(a.d[i]<b.d[i]){
    //            a.d[i+1]--;
    //            a.d[i]+=10;
    //        }
    //        a.d[i]-=b.d[i];
    //    }
    //    l++;
    //    while(a.d[l]<0){a.d[l]+=10;a.d[l+1]--;l++;}
    //    while(a.d[a.l]==0) a.l--;
    //}
    void cheng(big &a,ll b){
        ll g=0,l=a.l;
        for(int i=1;i<=l;i++){
            ll t=a.d[i]*b+g;
            a.d[i]=t%10;
            g=t/10;
        }
        l++;
        while(g){
            a.d[l]=g%10;
            g/=10;
            l++;
        }
        a.l=l-1;
    }
    void cpy(big &a,big &b){//a<---b
        a.l=b.l;
        for(int i=b.l;i>=1;i--) a.d[i]=b.d[i];
    }
    int main(){
        freopen("spring.in","r",stdin);
        freopen("spring.out","w",stdout);
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1;i<=len;i++) a.d[len-i+1]=s[i]-'0';
        a.l=len;               //printf("l %d
    ",a.l);for(int i=a.l;i>=1;i--) printf("%c",a.d[i]+'0);
        scanf("%s",s+1);
        len=strlen(s+1);
        for(int i=1;i<=len;i++) b.d[len-i+1]=s[i]-'0';
        b.l=len;
        if(!check(a,b)) printf("0");
        else{
            ll l=1,r=INF,ans=-1;
            while(l<=r){//printf("%d %d
    ",l,r);
                ll m=(l+r)/2;
                cpy(c,b);
                cheng(c,m);   //printf("new
    l %d m %d
    ",c.l,m);for(int i=c.l;i>=1;i--) printf("%c",c.d[i]+'0');cout<<"
    ";
                if(check(a,c)){ans=max(ans,m);l=m+1;}
                else r=m-1; 
            }
            printf("%d",ans);
        }
        
    }



    Problem 3

    琪露诺(iceroad.cpp/c/pas)

    题目描述

    在幻想乡,琪露诺是以笨蛋闻名的冰之妖精。某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来。但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸。于是琪露诺决定到河岸去追青蛙。小河可以看作一列格子依次编号为0到N,琪露诺只能从编号小的格子移动到编号大的格子。而且琪露诺按照一种特殊的方式进行移动,当她在格子i时,她只会移动到i+L到i+R中的一格。你问为什么她这么移动,这还不简单,因为她是笨蛋啊。每一个格子都有一个冰冻指数A[i],编号为0的格子冰冻指数为0。当琪露诺停留在那一格时就可以得到那一格的冰冻指数A[i]。琪露诺希望能够在到达对岸时,获取最大的冰冻指数,这样她才能狠狠地教训那只青蛙。但是由于她实在是太笨了,所以她决定拜托你帮它决定怎样前进。开始时,琪露诺在编号0的格子上,只要她下一步的位置编号大于N就算到达对岸。

    输入格式

    第1行:3个正整数N, L, R

    第2行:N+1个整数,第i个数表示编号为i-1的格子的冰冻指数A[i-1]

    输出格式

    第1行:一个整数,表示最大冰冻指数。保证不超过2^31-1

    第2行:空格分开的若干个整数,表示琪露诺前进的路线,最后输出-1表示到达对岸

    输入样例

    5 2 3

    0 12 3 11 7 -2

    输出样例

    11

    0 3 -1

    数据范围

    对于60%的数据:N <= 10,000

    对于100%的数据:N <= 200,000

    对于所有数据 -1,000 <= A[i] <= 1,000且1 <= L <= R <= N

    注意

    此题采用Special Judge


    改了一下题目不要求路径

    很明显DP,暴力的话n^2不行,然后想到了单调队列

    对于i,用单调队列维护[i-r,i-l],然后入队i-l+1

    因为只要超过n,所以最优解最远到N+r-1

    f[i]表示到i的话有一个问题,不知道i这个店能不能从0到达,所以倒着来,答案就是f[0]

    比赛时直接把w序列给倒过来了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=4e5+5;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,l,r,w[N];
    int f[N],q[N],head=1,tail=0;
    void dp(){
        n=n+r-1;
        for(int i=1;i<=n/2;i++) swap(w[i],w[n-i+1]);
        for(int i=1;i<=n+1;i++){
            while(head<=tail&&q[head]<i-r) head++;
            if(head>tail) f[i]=w[i];
            else f[i]=f[q[head]]+w[i];
            int nw=i-l+1;
            if(nw>=0) while(head<=tail&&f[q[tail]]<f[nw]) tail--;
            q[++tail]=nw;
            //printf("%d %d  %d   %d %d
    ",i,w[i],f[i],q[head],q[tail]);
        }
    }
    
    int main(){
        freopen("iceroad.in","r",stdin);
        freopen("iceroad.out","w",stdout);
        n=read();l=read();r=read();
        for(int i=0;i<=n;i++) w[i]=read(); 
        dp();
        printf("%d",f[n+1]);
    }



    Problem 4

    上白泽慧音(classroom.cpp/c/pas)

    题目描述

    在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为<A,B>。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足<X,Y>。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,3,4和2,5,6这两个最大连通区域时,输出的是1,3,4。

    输入格式

    第1行:两个正整数N,M

    第2..M+1行:每行三个正整数a,b,t, t = 1表示存在从村庄a到b的单向道路,t = 2表示村庄a,b之间存在双向通行的道路。保证每条道路只出现一次。

    输出格式

    第1行: 1个整数,表示最大的绝对连通区域包含的村庄个数。

    第2行:若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。

    输入样例

    5 5

    1 2 1

    1 3 2

    2 4 2

    5 1 2

    3 5 1

    输出样例

    3

    1 3 5

    数据范围

    对于60%的数据:N <= 200且M <= 10,000

    对于100%的数据:N <= 5,000且M <= 50,000

         

    第一眼,并查集、

    第二眼,有向?!强连通分量.........完了tarjan完全忘了

    打了一下暴力不太好做就弃疗了

    60:floyd传递闭包+并查集维护

    应该想到的

    PS:字典序最小就是集合中最小点最小

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=5005,M=5e4+5;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,a,b,flag,d[N][N];
    void floyd(){
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    d[i][j]=d[i][j]||(d[i][k]&&d[k][j]);
    }
    int fa[N],mn[N],size[N];
    inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    int main(int argc, const char * argv[]){
        freopen("classroom.in","r",stdin);
        freopen("classroom.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++){
            a=read();b=read();flag=read();
            if(flag==1) d[a][b]=1;
            else d[a][b]=d[b][a]=1;
        }
        floyd();
        for(int i=1;i<=n;i++) fa[i]=mn[i]=i,size[i]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(d[i][j]&&d[j][i]){//printf("%d %d
    ",i,j);
                    int x=find(i),y=find(j);
                    if(x!=y){
                        fa[y]=x;
                        mn[x]=min(mn[x],mn[y]);
                        size[x]+=size[y];//printf("f %d %d %d
    ",x,y,size[x]);
                    }
                }
        int mx=0,ans;
        for(int i=1;i<=n;i++){
            if(size[i]>mx){mx=size[i];ans=i;}
            if(size[i]==mx&&mn[i]<mn[ans]) ans=i; 
        }
        printf("%d
    ",size[ans]);
        for(int i=1;i<=n;i++) if(d[i][ans]&&d[ans][i]) printf("%d ",i);
    }

    100分:tarjan求强连通分量

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=5005,M=5e4+5;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct edge{
        int v,ne;
    }e[M<<1];
    int h[N],cnt=0;
    inline void add(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
    }
    int n,m,a,b,flag;
    int dfn[N],low[N],belong[N],size[N],dfc,scc;
    int st[N],top=0;
    void dfs(int u){//printf("dfs %d
    ",u);
        dfn[u]=low[u]=++dfc;
        st[++top]=u;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!dfn[v]){
                dfs(v);
                low[u]=min(low[u],low[v]);
            }else if(!belong[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            scc++;
            while(true){
                int x=st[top--];
                belong[x]=scc;
                size[scc]++;
                if(x==u) break;
            }
        }
    }
    int main(int argc, const char * argv[]){
        freopen("classroom.in","r",stdin);
        //freopen("classroom.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++){
            a=read();b=read();flag=read();
            if(flag==1){add(a,b);}
            else {add(a,b);add(b,a);}
        }
        for(int i=1;i<=n;i++) if(!belong[i]) dfs(i);
        int mx=0,ans;
        for(int i=1;i<=n;i++) if(size[belong[i]]>mx){
            mx=size[belong[i]];ans=belong[i];
        }
        printf("%d
    ",mx);
        for(int i=1;i<=n;i++) if(belong[i]==ans) printf("%d ",i); 
    }
  • 相关阅读:
    MyBatis(第三方缓存整合原理&ehcache适配包下载)
    MyBatis(缓存机制)
    MyBatis(动态SQL2)
    MyBatis(动态SQL)
    MyBatis(映射文件中使用foreach标签时报错,属性collection的问题)
    MyBatis映射文件(编写SQL语句;可有可无(无的时候,使用注解编程))
    Python virtualenv with Sublime Text 3
    python & mongo问题记录
    CentOS On VirtualBox
    MySQL GROUP BY用法
  • 原文地址:https://www.cnblogs.com/candy99/p/5988410.html
Copyright © 2020-2023  润新知