zoukankan      html  css  js  c++  java
  • 洛谷八连测第一轮

    T1

    SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。

    题目描述

    SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

    这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

    SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

    但是SOL菌太菜了于是请你帮忙。

    输入输出格式

    输入格式:

     

    每组输入仅包含一行:两个整数n,k。

     

    输出格式:

     

    输出一个整数:n!在k进制下后缀0的个数。

     

    输入输出样例

    输入样例#1:
    10 40
    输出样例#1:
    2

    说明

    对于20%的数据,n <= 1000000, k = 10

    对于另外20%的数据,n <= 20, k <= 36

    对于100%的数据,n <= 10^12,k <= 10^12

    ————————————————————————————

    这道题其实就是判断一下n!是否是n^k的倍数 k取个max就是答案了

    但是因为n这么大 你不可能直接算 这个时候就要分解质因数取个min辣

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define LL long long
    using std::min;
    LL n,k,ans;
    LL q[1007],cnt,h[1007];
    void prepare(){
        for(LL x=2;x*x<=k;x++)if(k%x==0){
            q[++cnt]=x;
            while(k%x==0) h[cnt]++,k/=x;
        }
        if(k!=1) q[++cnt]=k,h[cnt]=1;
    }
    int main(){
        while(scanf("%lld %lld",&n,&k)==2){
            memset(h,0,sizeof(h));
            ans=0x7fffffffffffffff; 
            cnt=0; prepare();
            for(int i=1;i<=cnt;i++){
                LL ly=0;
                for (long long x=q[i];x<=n;x*=q[i]) ly+=n/x;
                ans=min(ans,ly/h[i]);
            }printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    T2

    题目背景

    小强和阿米巴是好朋友。

    题目描述

    小强喜欢数列。有一天,他心血来潮,写下了三个长度均为n的数列。

    阿米巴也很喜欢数列。但是他只喜欢其中一种,波动数列。

    阿米巴把他的喜好告诉了小强。小强便打算找出这三个数列内的最长波动数列。

    也就是说,如果我们将三个数列记做a[n][3],他必须要构造一个二元组序列:<p[i], q[i]>,使得对于任何 i>1 有:

    p[i] > p[i-1]

    若q[i] = 0,a[p[i]][q[i]] >= a[p[i-1]][q[i-1]]

    若q[i] = 1,a[p[i]][q[i]] <= a[p[i-1]][q[i-1]]

    若q[i] = 2,只要保持段内同向即可(就是对于连续的一段q[i]=2,要么都有a[p[i]][q[i]] >= a[p[i-1]][q[i-1]],要么都有a[p[i]][q[i]] <= a[p[i-1]][q[i-1]])。

    小强希望这个二元组序列尽可能长。

    提示:当q[i] != q[i-1]时,数列的增减性由q[i]而非q[i-1]决定。

    清晰版题目描述

    小强拿到一个3×n的数组,要在每一列选一个数(或者不选),满足以下条件:

    1.如果在第一行选,那它必须大于等于上一个数

    2.如果在第二行选,那么必须小于等于上一个数

    3.如果在第三行选,对于连续的一段在第三行选的数,必须满足方向相同(都小于等于上一个数或者都大于等于上一个数)

    输入输出格式

    输入格式:

     

    输入包含4行。

    第一行一个数n,表示数列长度。

    第2、3、4行,每行n个整数,分别表示三个数列。

     

    输出格式:

     

    输出仅包含一个整数,即最长波动数列的长度。

     

    输入输出样例

    输入样例#1:
    6
    1 2 3 6 5 4
    5 4 3 7 8 9
    1 2 3 6 5 4
    
    输出样例#1:
    6

    说明

    对于20%的数据,n <= 10, m <= 1000

    对于60%的数据,n <= 1000, m <= 1000

    对于100%的数据, n <= 100000, m <= 1000000000

    其中m = max|a[i]|

    样例解释:

    取第三行1 2 3(增),然后取第1行6(增),然后取第三行5 4(减),长度为6。

    这道题f[i][0/1/2/3]分别表示在第i列第j行(0增1减2(2)增3(3)减)

    暴力是枚举前面所有行 复杂度n^2 树状数组维护一下前(后)缀和就可以辣

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::max;
    using std::sort;
    using std::unique;
    using std::lower_bound;
    const int M=4e5+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int ans,f[M][15],n,v[M][15];
    int q[3*M],cnt;
    #define lowbit(x) x&-x
    struct pos{
        int s[3*M];
        pos(){memset(s,0,sizeof(s));}
        //qian
        void ins2(int x,int w){
            while(x<=cnt){
                s[x]=max(s[x],w);
                x+=lowbit(x);
            }
        }
        int push2(int x){
            int ans=0;
            while(x){
                ans=max(ans,s[x]);
                x-=lowbit(x);
            }
            return ans;
        }
        //hou
        void ins1(int x,int w){
            while(x){
                s[x]=max(s[x],w);
                x-=lowbit(x);
            }
        }
        int push1(int x){
            int ans=0;
            while(x<=cnt){
                ans=max(ans,s[x]);
                x+=lowbit(x);
            }
            return ans;
        }
    }s0,s1,s2,s3;
    int main(){
        n=read();
        for(int j=0;j<=2;j++) for(int i=1;i<=n;i++) v[i][j]=read(),q[++cnt]=v[i][j];
        sort(q+1,q+1+cnt); cnt=unique(q+1,q+1+cnt)-q-1;
        for(int j=0;j<=2;j++) for(int i=1;i<=n;i++) v[i][j]=lower_bound(q+1,q+1+cnt,v[i][j])-q;
        f[1][0]=f[1][1]=f[1][2]=f[1][3]=1;
        s0.ins2(v[1][0],f[1][0]); s0.ins2(v[1][1],f[1][1]);
        s0.ins2(v[1][2],f[1][2]); s0.ins2(v[1][2],f[1][3]);
        s1.ins1(v[1][0],f[1][0]); s1.ins1(v[1][1],f[1][1]);
        s1.ins1(v[1][2],f[1][2]); s1.ins1(v[1][2],f[1][3]);
        s2.ins2(v[1][0],f[1][0]); s2.ins2(v[1][1],f[1][1]); s2.ins2(v[1][2],f[1][2]);
        s3.ins1(v[1][0],f[1][0]); s3.ins1(v[1][1],f[1][1]); s3.ins1(v[1][2],f[1][3]);
        for(int i=2;i<=n;i++){
            f[i][0]=1; f[i][0]=max(f[i][0],s0.push2(v[i][0])+1);
            f[i][1]=1; f[i][1]=max(f[i][1],s1.push1(v[i][1])+1);
            f[i][2]=1; f[i][2]=max(f[i][2],s2.push2(v[i][2])+1);
            f[i][3]=1; f[i][3]=max(f[i][3],s3.push1(v[i][2])+1);
            int sum=max(max(f[i][0],f[i][1]),max(f[i][2],f[i][3]));
            s0.ins2(v[i][0],f[i][0]); s0.ins2(v[i][1],f[i][1]);
            s0.ins2(v[i][2],f[i][2]); s0.ins2(v[i][2],f[i][3]);
            s1.ins1(v[i][0],f[i][0]); s1.ins1(v[i][1],f[i][1]);
            s1.ins1(v[i][2],f[i][2]); s1.ins1(v[i][2],f[i][3]);
            s2.ins2(v[i][0],f[i][0]); s2.ins2(v[i][1],f[i][1]); s2.ins2(v[i][2],f[i][2]);
            s3.ins1(v[i][0],f[i][0]); s3.ins1(v[i][1],f[i][1]); s3.ins1(v[i][2],f[i][3]);
            ans=max(ans,sum);
        }printf("%d
    ",ans);
        return 0;
    }
    View Code

    T3

    题目背景

    毒奶色和F91是好朋友。

    题目描述

    他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋。

    毒奶色觉得F91是一只鸡。他在一个n×n的棋盘上用黑色的城堡(车)、骑士(马)、主教(象)、皇后(副)、国王(帅)、士兵(卒)摆了一个阵。

    然而F91觉得毒奶色是一只鸡。他发起了挑战:他要操纵一个白色骑士,不经过任何一个棋子的攻击范围(F91可以连续行动,而毒奶色的棋子不会动,除非白骑士进入了对方的攻击范围),并击杀毒奶色的国王(即进入黑国王所在的位置)。

    请告诉F91他最少需要多少步骤来完成这一项壮举。

    注意:

    1.当F91的白骑士走到毒奶色的棋子所在的格子上的时候,会击杀(吃掉)该棋子。这个棋子也就不再对F91的白骑士有威胁了。

    2.如果白骑士开场就在黑子的攻击范围内,则立刻被击杀、F91立刻失败。

    3.即使白骑士在攻击王的瞬间进入了其他棋子攻击范围(即其他棋子“看护”着王所在的格子),依然算F91获胜。

    攻击范围:

    城堡:横、竖方向所有位置,直到被一个其他棋子阻拦。

    ..#..
    ..#..
    ##C##
    ..#..
    ..#..

    骑士:横2竖1或者横1竖2的所有位置(最多8个,类似日字)。

    .#.#.
    #...#
    ..K..
    #...#
    .#.#.

    主教:斜向(45°)所有位置,直到被一个其他棋子阻拦。

    #...#
    .#.#.
    ..B..
    .#.#.
    #...#

    皇后:城堡和主教的结合体(既能横/竖向攻击,也能45°角斜向攻击,直到被其他棋子阻挡)。

    #.#.#
    .###.
    ##Q##
    .###.
    #.#.#

    国王:身边8连通位置的8个格子。

    .....
    .###.
    .#X#.
    .###.
    .....

    士兵:左下方/右下方(45°)的格子(最多2个)。

    .....
    .....
    ..P..
    .#.#.
    .....

    其中字母表示棋子类型,参考输入格式。

    ‘#’表示可攻击范围。

    输入输出格式

    输入格式:

     

    输入包含多组数据。

    每一组数据中,第一行一个整数n表示棋盘规模。

    接下来n行,每行一个长度为n的字符串。描述棋盘的格局。

    其中:

    .表示空

    O表示白骑士

    C表示黑城堡

    K表示黑骑士

    B表示黑主教

    Q表示黒皇后

    X表示黑国王

    P表示黑士兵

     

    输出格式:

     

    对于每一个测试数据,每行输出一个整数,表示F91的最小步数。

    如果无论F91如何行动也无法击杀黑国王,输出-1。

     

    输入输出样例

    输入样例#1:
    8
    ...X....
    ........
    ........
    ........
    ........
    ........
    ........
    ......O.
    输出样例#1:
    4
    输入样例#2:
    8
    ......X.
    ........
    .O......
    ...P.Q.C
    .....B..
    ........
    ...K....
    ........
    输出样例#2:
    7

    说明

    输入最多包含5组数据。

    对于20%的数据,毒奶色只有国王。n <= 8。

    对于30%的数据,毒奶色只有国王、骑士。n <= 8。

    对于60%的数据,毒奶色只有国王、骑士、王后。n <= 50。

    对于100%的数据,毒奶色可以有全套16颗棋子(2城堡,2骑士,2主教,1后,1王,8兵)。n <= 50。

    温馨提示:

    时间限制可能比想象之中还要更紧一点,请注意实现细节以保证性能。

    样例2解释:

    一种可行的做法是:

    ......X.
    .3..6...
    .O5.....
    4.2P.Q.C
    1....B..
    ........
    ...K....
    ........

    这题有点小复杂QAQ
    因为棋子的最多16个而且王可以压掉还有黑骑士(因为骑士不可能吃骑士)所以就剩13个就可以压了
    f[i][j][s]表示走到i j 黑棋子的状态为s的步数 然后慢慢转移咯QAQ 预处理+bfs 6k+
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    const int inf=0x3f3f3f3f;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    char c[205][205];
    struct node{char c; int x,y;}f[1233];
    int n,cnt,sx,sy,ex,ey;
    int map[205][205];
    bool vis[(1<<13)+7][205][205],ly[205][205];
    int xx[8]={1,1,-1,-1,2,2,-2,-2},yy[8]={2,-2,2,-2,1,-1,1,-1};
    bool pd(int x,int y){return (x>=1&&x<=n&&y>=1&&y<=n);}
    void prepare(int s){
        int nx,ny;
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) vis[s][i][j]=ly[i][j];
        for(int i=0;(1<<i)<=s;i++)if((1<<i)&s){
            if(f[i].c=='C'){
                nx=f[i].x-1; ny=f[i].y;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x; ny=f[i].y-1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
            }
            else if(f[i].c=='B'){
                nx=f[i].x-1; ny=f[i].y-1;
                while(map[nx][ny]!=-inf&&pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x-1; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y-1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
            }
            else if(f[i].c=='Q'){
                nx=f[i].x-1; ny=f[i].y;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x; ny=f[i].y-1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x-1; ny=f[i].y-1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x-1; ny=f[i].y+1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx--,ny++;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
                nx=f[i].x+1; ny=f[i].y-1;
                while(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]==-1||!(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1,nx++,ny--;
                if(pd(nx,ny)&&map[nx][ny]!=-inf&&(map[nx][ny]!=-1&&(s&(1<<map[nx][ny])))) vis[s][nx][ny]=1;
            }
            else if(f[i].c=='P'){
                vis[s][f[i].x+1][f[i].y+1]=1;
                vis[s][f[i].x+1][f[i].y-1]=1;
            }
        }
    }
    struct pos{int x,y,step,s;};
    std::queue<pos>q;
    bool ca[(1<<13)+7][55][55];
    void bfs(){
        while(!q.empty()) q.pop();
        q.push((pos){sx,sy,0,(1<<cnt)-1});
        ca[(1<<cnt)-1][sx][sy]=1;
        if(vis[(1<<cnt)-1][sx][sy]){printf("-1
    "); return ;}
        while(!q.empty()){
            pos p=q.front(); q.pop();
            int s=p.s;
            for(int i=0;i<8;i++){
                int nx=p.x+xx[i],ny=p.y+yy[i];
                if(nx==ex&&ny==ey){printf("%d
    ",p.step+1); return ;}
                if(map[nx][ny]==-inf||nx<1||nx>n||ny<1||ny>n||(vis[s][nx][ny])||ca[s][nx][ny]) continue;
                if(map[nx][ny]!=-1&&((1<<map[nx][ny])&s)) q.push((pos){nx,ny,p.step+1,s-((1<<map[nx][ny])&s)}),ca[s-((1<<map[nx][ny])&s)][nx][ny]=1;
                else q.push((pos){nx,ny,p.step+1,s}),ca[s][nx][ny]=1;
            }
        }
        printf("-1
    ");
    }
    int main(){
        //freopen("gg.out","r",stdin);
        while(scanf("%d",&n)==1){
            cnt=0;
            memset(ly,0,sizeof(ly));
            memset(vis,0,sizeof(vis));
            memset(ca,0,sizeof(ca));
            memset(map,0,sizeof(map));
            for(int i=1;i<=n;i++) scanf("%s",c[i]+1);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(c[i][j]=='.') map[i][j]=-1;
                    else if(c[i][j]=='O') sx=i,sy=j,map[i][j]=-1;
                    else if(c[i][j]=='X'){
                        map[i][j]=-inf;
                        ex=i; ey=j;
                        if(j>1) ly[i][j-1]=1; if(j<n) ly[i][j+1]=1;
                        if(i>1) ly[i-1][j]=1; if(i<n) ly[i+1][j]=1;
                        if(i>1&&j>1) ly[i-1][j-1]=1; if(i&&j<n) ly[i-1][j+1]=1;
                        if(i<n&&j>1) ly[i+1][j-1]=1; if(i<n&&j<n) ly[i+1][j+1]=1;
                    }
                    else if(c[i][j]=='K'){
                        map[i][j]=-inf;
                        for(int k=0;k<8;k++) if(pd(i+xx[k],j+yy[k])) ly[i+xx[k]][j+yy[k]]=1;
                    }
                    else f[cnt]=(node){c[i][j],i,j},map[i][j]=cnt++;
                }
            }
            for(int s=0;s<(1<<cnt);s++) prepare(s); 
            //for(int s=0;s<(1<<cnt);s++,puts("")) for(int i=1;i<=n;i++,puts("")) for(int j=1;j<=n;j++) printf("[%d] ",vis[s][i][j]); puts("");
            bfs();
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    php删除最后一个字符
    git删除远程分支
    lsof命令
    高效率的全组合算法(Java版实现)
    Java类变量和成员变量初始化过程
    pig命令行快捷键
    java的HashCode方法
    待学习
    长连接和短连接
    Hadoop学习之SecondaryNameNode
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7635988.html
Copyright © 2011-2022 走看看