zoukankan      html  css  js  c++  java
  • 9.2NOIP模拟题

     

    9.2 NOIP模拟 

    题目名称

    “与”

    小象涂色

    行动!行动!

    输入文件

    and.in

    elephant.in

    move.in

    输出文件

    and.out

    elephant.in

    move.in

    时间限制

    1s

    1s

    1s

    空间限制

    64MB

    128MB

    128MB

    “与”

    (and.pas/.c/.cpp)

    时间限制:1s;空间限制64MB

    题目描述:

    给你一个长度为n的序列A,请你求出一对Ai,Aj(1<=i<j<=n)使Ai“与”Aj最大。

    Ps:“与”表示位运算and,在c++中表示为&。

    输入描述:

    第一行为n。接下来n行,一行一个数字表示Ai。

    输出描述:

    输出最大的Ai“与”Aj的结果。

    样例输入:

    3

    8

    10

    2

    样例输出:

    8

    样例解释:

    8 and 10 = 8

    8 and 2 = 0

    10 and 2 = 2

    数据范围:

    20%的数据保证n<=5000

    100%的数据保证 n<=3*10^5,0<=Ai<=10^9

    /*
    "与"是要求同一位均是1,结果才为1。而对于2进制,越高位有1,数字越大。
    所以我们可以考虑将所给数列的数字看成二进制,从二进制最高位向下枚举
    若有大于等于两个数"这一位上为1",那么最终结果的这一位肯定是1,
    于是我们就可以将所有"这一位上为1"的数保留下来,
    剩下的数舍弃;而若有少于两个数"这一位上为1",则这一位上一定为0。
    */ 
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    int n,a[300002],d[35],ans;
    
    void init()
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++) scanf("%d",&a[i]);
    }
    
    void find()
    {
        int i,j,ct,now=n,t;
        for(i=30; i>=0; i--)
        {
            ct=0;
            for(j=1; j<=now; j++) if(a[j]&(1<<i)) ct++;
            if(ct<2) continue;
            t=0;d[i]=1;
            for(j=1; j<=now; j++) if(a[j]&(1<<i)) a[++t]=a[j];
            now=t;
        }
        for(i=30; i>=0; i--) if(d[i]) ans=ans^(1<<i);
        printf("%d
    ",ans);
    }
    
    int main()
    {
        freopen("and.in","r",stdin);
        freopen("and.out","w",stdout);
        init();find();
        return 0;
    }

     

      

    小象涂色

    (elephant.pas/.c/.cpp)

    时间限制:1s,空间限制128MB

    题目描述:

    小象喜欢为箱子涂色。小象现在有c种颜色,编号为0~c-1;还有n个箱子,编号为1~n,最开始每个箱子的颜色为1。小象涂色时喜欢遵循灵感:它将箱子按编号排成一排,每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选0个),为之涂上随机一种颜色。若一个颜色为a的箱子被涂上b色,那么这个箱子的颜色会变成(a*b)mod c。请问在k次涂色后,所有箱子颜色的编号和期望为多少?

    输入描述:

    第一行为T,表示有T组测试数据。

    对于每组数据,第一行为三个整数n,c,k。

    接下来k行,每行两个整数Li,Ri,表示第i个操作的L和R。

    输出描述:

    对于每组测试数据,输出所有箱子颜色编号和的期望值,结果保留9位小数。

    样例输入:

    3

    3 2 2

    2 2

    1 3

    1 3 1

    1 1

    5 2 2

    3 4

    2 4

    样例输出:

    2.062500000

    1.000000000

    3.875000000

    数据范围:

    40%的数据1 <= T <= 5,1 <= n, k <= 15,2 <= c <= 20

    100%的数据满足1 <= T <= 10,1 <= n, k <= 50,2 <= c <= 100,1 <= Li <= Ri <= n

    /*
    dp[i][j][k]表示第i个箱子第j次染色,染为k颜色的概率。
    时间复杂度过高,只能拿部分分
    对于每个箱子,它们的本质是相同的,也就是第几个箱子这一维状态是不需要存在的。
    dp[i][j]表示染色i次颜色为j的概率
      dp[i+1][j]+=dp[i][j]/2; 上次不染色 
      dp[i+1][j*x%c]+=dp[i][j] /2 /c; (x枚举颜色) 上次染色,染成x 
    最后期望Σdp[cnt[i]][j]*j; 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 107
    
    using namespace std;
    int n,m,tot,c,k,t,l,r,cnt[N];
    double dp[N][N],ans;
    
    void init()
    {
        memset(dp,0,sizeof dp);
        memset(cnt,0,sizeof cnt);
        tot=0;ans=0;
        scanf("%d%d%d",&n,&c,&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d",&l,&r);
            for(int j=l;j<=r;j++)
            {
                cnt[j]++;tot=max(tot,cnt[j]);
            }
        }
    }
    
    void DP()
    {
        dp[0][1]=1;
        for(int i=0;i<tot;i++)
        {
            for(int j=0;j<c;j++) 
            {
                dp[i+1][j]+=dp[i][j]/2;
                for(int x=0;x<c;x++) dp[i+1][(j*x)%c]+=dp[i][j]/(2*c);
            }
        }
        
        for(int i=1;i<=n;i++)
          for(int j=0;j<c;j++)
            ans+=dp[cnt[i]][j]*j;
        printf("%.9f
    ",ans);
    }
    
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            init();DP();
        }        
        return 0;
    }

     

     

     

     

     

    行动!行动!

    (move.pas/.c/.cpp)

    时间限制:1s;空间限制:128MB

    题目描述:

    大CX国的大兵Jack接到一项任务:敌方占领了n座城市(编号0~n-1),有些城市之间有双向道路相连。Jack需要空降在一个城市S,并徒步沿那些道路移动到T城市。虽然Jack每从一个城市到另一个城市都会受伤流血,但大CX国毕竟有着“过硬”的军事实力,它不仅已经算出Jack在每条道路上会损失的血量,还给Jack提供了k个“简易急救包”,一个包可以让Jack在一条路上的流血量为0。Jack想知道自己最少会流多少血,不过他毕竟是无脑的大兵,需要你的帮助。

    输入描述:

    第一行有三个整数n,m,k,分别表示城市数,道路数和急救包个数。

    第二行有两个整数,S,T。分别表示Jack空降到的城市编号和最终要到的城市。

    接下来有m行,每行三个整数a,b,c,表示城市a与城市b之间有一条双向道路。

    输出描述:

    Jack最少要流的血量。

    样例输入:

    5 6 1

    0 3

    3 4 5

    0 1 5

    0 2 100

    1 2 5

    2 4 5

    2 4 3

    样例输出:

    8

    数据范围:

    对于30%的数据,2<=n<=50,1<=m<=300,k=0;

    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

    /*
    分层图spfa 应该只有70,卡spfa...要加优化,懒得加了。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 10001
    #define M 100001
    
    using namespace std;
    int head[N],d[N][11],q[M][2];
    bool inq[N][11];
    int n,m,k,st,ed,cnt;
    struct edge
    {
        int u,to,dis,next;
    }e[M];
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    inline void add(int u,int to,int dis)
    {
        e[++cnt].to=to;e[cnt].dis=dis;e[cnt].next=head[u];head[u]=cnt;
    }
    
    void spfa()
    {
        memset(d,127/3,sizeof d);
        int he=0,ta=1;
        q[0][0]=st;q[0][1]=0;
        inq[st][0]=1;d[st][0]=0;
        while(he!=ta)
        {
            int now=q[he][0],tmp=q[he++][1];inq[now][tmp]=0;
            if(he==100001) he=0;
            for(int i=head[now];i;i=e[i].next)
            {
                int v=e[i].to;
                if(d[v][tmp]>d[now][tmp]+e[i].dis)
                {
                    d[v][tmp]=d[now][tmp]+e[i].dis;
                    if(!inq[v][tmp])
                    {
                        q[ta][0]=v;q[ta++][1]=tmp;
                        inq[v][tmp]=1;
                        if(ta==100001) ta=0;
                    }
                }
                if(d[v][tmp+1]>d[now][tmp] && tmp<k)
                {
                    d[v][tmp+1]=d[now][tmp];
                    if(!inq[v][tmp+1])
                    {
                        inq[v][tmp+1]=1;
                        q[ta][0]=v;q[ta++][1]=tmp+1;
                        if(ta==100001) ta=0;
                    }
                }
            }
        }
        int ans=0x7fffffff;
        for(int i=0;i<=k;i++) ans=min(ans,d[ed][i]);
        printf("%d",ans);
    }
    
    int main()
    {
        int x,y,z;
        n=read();m=read();k=read();
        st=read();ed=read();
        while(m--)
        {
            x=read();y=read();z=read();
            add(x,y,z);add(y,x,z);
        }
        spfa();
        return 0;
    } 
    

      

    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    过滤评论中的表情
    谈谈你对多进程,多线程,以及协程的理解
    什么是多线程竞争?
    解释以下什么是锁,有哪几种锁?
    .什么是死锁
    多线程交互访问数据,如果访问到了就不访问了?
    什么是线程安全,什么是互斥锁
    说说下面几个概念:同步,异步,阻塞,非阻塞?
    什么是僵尸进程和孤儿进程?怎么避免僵尸进程?
    python中进程与线程的使用场景
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7466767.html
Copyright © 2011-2022 走看看