1. 程式人生 > >9.2NOIP模擬題

9.2NOIP模擬題

lpad 相同 ios pri ron color cstring 解釋 染色

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模擬題