码迷,mamicode.com
首页 > 其他好文 > 详细

9.2NOIP模拟题

时间:2017-09-02 16:56:05      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:随机   ++   iostream   优化   style   题目   center   for   table   

 

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\n",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\n",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;
} 

  

9.2NOIP模拟题

标签:随机   ++   iostream   优化   style   题目   center   for   table   

原文地址:http://www.cnblogs.com/L-Memory/p/7466767.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!