zoukankan      html  css  js  c++  java
  • 170902模拟赛

    题目名称

    “与”

    小象涂色

    行动!行动!

    输入文件

    and.in

    elephant.in

    move.in

    输出文件

    and.out

    elephant.in

    move.in

    时间限制

    1s

    1s

    1s

    空间限制

    64MB

    128MB

    128MB

    测评环境:windows XP

    比赛时间:3小时

    得分情况

    蒟蒻我才得了180分,其他大佬肯定都AK了;

    T1,20min正解思路10min写完,A掉了;

    T2,一眼概率DP,然而根本看不懂题目什么意思;

    T3,思路纠结了近1h,然后30min写代码,然后数组开小了,这样80,其实开够的话也还会T一个点;

    “与”

    (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

    思路

    从高位开始筛选;

    如果有至少两个数该位(f)存在,则ans+=f并且筛去&f==0的数;

    因为某位后所有位的数的和不可能大于本位的数,所以可以这样做;

    代码实现

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=3e5+10;
     5 inline int max_(int x,int y){return x>y?x:y;}
     6 int n,f,big,now,ans;
     7 int s[maxn];
     8 bool comp(int a,int b){return (a&f)>(b&f);}
     9 int main(){
    10     freopen("and.in","r",stdin);
    11     freopen("and.out","w",stdout);
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++){
    14         scanf("%d",&s[i]);
    15         big=max_(big,s[i]);
    16     }
    17     for(f=1;f<=big;f<<=1);
    18     for(f>>=1;f;f>>=1){
    19         sort(s+1,s+n+1,comp);
    20         for(now=1;s[now]&f&&now<=n;now++);
    21         if(now>2){ans+=f,n=now-1;}
    22     }
    23     printf("%d
    ",ans);
    24     return 0;
    25 }

    小象涂色

    (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

    思路

     f[i][j]表示一个物品操作i次颜色变为j的概率;

    时间复杂度O(T*K*c2);

    代码实现

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 inline int max_(int x,int y){return x>y?x:y;}
     5 const int maxn=55;
     6 int T,n,c,maxc;
     7 int cs[maxn];
     8 double f[maxn][maxn<<1];
     9 void init(){
    10     memset(cs,0,sizeof(cs));
    11     int k,x,y;maxc=0;
    12     scanf("%d%d%d",&n,&c,&k);
    13     for(int i=1;i<=k;i++){
    14         scanf("%d%d",&x,&y);
    15         for(int j=x;j<=y;j++){
    16             cs[j]++;
    17             maxc=max_(maxc,cs[j]);
    18         }
    19     }
    20 }
    21 void dp(){
    22     memset(f,0,sizeof(f));
    23     double ans=0;
    24     f[0][1]=1;
    25     for(int i=0;i<maxc;i++)
    26     for(int j=0;j<c;j++){
    27         f[i+1][j]+=f[i][j]/2;
    28         for(int k=0;k<c;k++) f[i+1][(j*k)%c]+=f[i][j]/c/2;
    29     }
    30     for(int i=1;i<=n;i++)
    31     for(int j=0;j<c;j++)
    32     ans+=f[cs[i]][j]*j;
    33     printf("%.9lf
    ",ans);
    34 }
    35 int main(){
    36     freopen("elephant.in","r",stdin);
    37     freopen("elephant.out","w",stdout);
    38     scanf("%d",&T);
    39     while(T--){
    40         init();
    41         dp();
    42     }
    43     return 0;
    44 }

    行动!行动!

    (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.

    思路

     d[i][j]表示使用j个医疗包的情况下,跑到i城市的流血量;

    然后跑一边SPFA,求的最短路即可;

    最重要的是,这个题需要优化,,,使用SLF方案优化SPFA;

    代码实现

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=1e4+10;
     4 const int maxm=1e5+10;
     5 inline int min_(int x,int y){return x<y?x:y;}
     6 int n,m,k,s,t;
     7 int h[maxn],hs;
     8 int et[maxm],en[maxm],ew[maxm];
     9 int d[maxn][12];
    10 void add(){
    11     int a,b,c;
    12     scanf("%d%d%d",&a,&b,&c);
    13     hs++,et[hs]=b,ew[hs]=c,en[hs]=h[a],h[a]=hs;
    14     hs++,et[hs]=a,ew[hs]=c,en[hs]=h[b],h[b]=hs;
    15 }
    16 int q[maxm][2],head,tail;
    17 bool v[maxn][12];
    18 void SPFA(){
    19     memset(d,0x7f,sizeof(d));
    20     d[s][0]=0,v[s][0]=1;
    21     q[tail][0]=s,q[tail][1]=0,tail++;
    22     int a,b;
    23     while(head!=tail){
    24         a=q[head][0];
    25         b=q[head][1];
    26         v[a][b]=0;
    27         head=(head+1)%maxm;
    28         for(int i=h[a];i;i=en[i]){
    29             if(0ll+ew[i]+d[a][b]<0ll+d[et[i]][b]){
    30                 d[et[i]][b]=ew[i]+d[a][b];
    31                 if(!v[et[i]][b]){
    32                     v[et[i]][b]=1;
    33                     if(d[et[i]][b]<d[q[head][0]][q[head][1]]){
    34                         head=(head+maxm-1)%maxm;
    35                         q[head][0]=et[i];
    36                         q[head][1]=b;
    37                     }
    38                     else{
    39                         q[tail][0]=et[i];
    40                         q[tail][1]=b;
    41                         tail=(tail+1)%maxm;
    42                     }
    43                 }
    44             }
    45             if(b<k&&d[a][b]<d[et[i]][b+1]){
    46                 d[et[i]][b+1]=d[a][b];
    47                 if(!v[et[i]][b+1]){
    48                     v[et[i]][b+1]=1;
    49                     if(d[et[i]][b+1]<d[q[head][0]][q[head][1]]){
    50                         head=(head+maxm-1)%maxm;
    51                         q[head][0]=et[i];
    52                         q[head][1]=b+1;
    53                     }
    54                     else{
    55                         q[tail][0]=et[i];
    56                         q[tail][1]=b+1;
    57                         tail=(tail+1)%maxm;
    58                     }
    59                 }
    60             }
    61         }
    62     }
    63 }
    64 int main(){
    65     freopen("move.in","r",stdin);
    66     freopen("move.out","w",stdout);
    67     scanf("%d%d%d",&n,&m,&k);
    68     scanf("%d%d",&s,&t);
    69     for(int i=1;i<=m;i++) add();
    70     SPFA();
    71     printf("%d
    ",d[t][k]);
    72     return 0;
    73 }
  • 相关阅读:
    POJ 1019 组合计数
    POJ 3252 组合计数
    SPJ 与 Student 数据库的创建于数据插入
    POJ 1496 POJ 1850 组合计数
    Java常用类库--大数处理类
    POJ 2492 并查集应用的扩展
    POJ 3268 双向Dijkstra
    线段树(带删除节点)
    西工大10级保研机试 柱状图
    KMP专场 POJ
  • 原文地址:https://www.cnblogs.com/J-william/p/7466629.html
Copyright © 2011-2022 走看看