第十一屆北師大程序設計競賽 by Zoo

現場賽

team06 BJTU-01

隊員:Ronnoc(5),MuQ~(4)

總共9 of 12

rank 1

以爲被北航逆襲了

結果過了D的不是他們

榜單出來了...http://www.bnuoj.com/bnucpc/summary.htm

某北航罰時還被超了...

第一妥妥的

感覺3個沒有出來的題DEG

D是樹,E是貪心+搜索,G是搜索

沒有全場的FB,只有I是局部的FB

表示有一個CE很憂傷....

報告

A題,MuQ~ 1Y

打表水題

#include<stdio.h>
int main()
{
    char c[20][100]={"\0",
                     "Unknown\0",
                     "Spring Training\0",
                     "Spring Training\0",
                     "Spring Training\nBNU Contest\0",
                     "Unknown\0",
                     "Unknown\0",
                     "Practice Week\nSummer Training\0",
                     "Summer Training\0",
                     "Regional Contest\0",
                     "Regional Contest\0",
                     "Basic Training\nRegional Contest\0",
                     "Basic Training\nRookie Contest\0"};
    int i,j,k,n;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
       scanf("%d",&j);
       printf("%s\n",c[j]);
    }
    scanf("%d");
    return 0;
}


B題

MuQ~,不知道什麼題,也不知道幾Y,反正是過了

3Y

#include<stdio.h>
int main()
{
    int a[1020][10],t,i,j,k,kk,n,l,x,y[10000];
    scanf("%d",&t);
    while(t--)
    {
       for(i=0;i<1020;i++)
          for(j=0;j<10;j++)
             a[i][j]=0;
       scanf("%d%d%d",&l,&x,&n);
       for(i=1;i<=n;i++)
          scanf("%d",&y[i]);
      a[x][0]=1;
      for(j=1;j<=4;j++)
       for(i=x+1;i<=l;i++)
          for(k=1;k<=n;k++)
             if(i-y[k]>=0)
                if(a[i-y[k]][j-1])
                   a[i][j]=1;
       if(a[l][4])printf("Yes\n");
       else printf("No\n");
    }
    return 0;
}


C題

水題,可行的步數統計,奇偶性判斷2Y

1CE...沒有引用stdio的頭文件

#include<math.h>
#include<stdio.h>
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int L,H;
        scanf("%d%d",&L,&H);
        int res=0;
        while(L%2==0&&L)L/=2,res++;
        while(H%2==0&&H)H/=2,res++;
        if(res%2)printf("Adidas loses\n");
        else printf("Adivon prevails\n");
        }
    return 0;
    }

F題

直接dp遞推1TLE

心裏面有個dp表格

dp[i][j]表示第i個元素拍中且是第j個連續的概率

轉移方程

dp[i][0]=1-p

dp[i][j]=dp[i-1][j-1]*p

然後結果是FOR(i,1,n)FOR(j,1,i)res+=dp[i][j]*j;

這個事第一次的結果

然後手寫出公式發現每一行可以O(1)的求出和

總O(n)

2Y

看程序

#include<stdio.h>
#define N 1010
double dp[N][N];
double sum[N],cha[N]; 
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        double p;
        scanf("%d%lf",&n,&p);
        int i,j;
        cha[1]=(1-p)*p;
        sum[1]=p+cha[1]*(n-1);
        for(i=2;i<=n;i++){
            sum[i]=(sum[i-1]-cha[i-1])*p;
            cha[i]=cha[i-1]*p;
            }
        double res=0;
        for(i=1;i<=n;i++)res+=i*sum[i];
        printf("%.6lf\n",res);
        }    
    return 0;
    }

H題

概率題

ai表示到剛好第i步的期望

推下公式即可

1RE數組開小了

2TLE時間開大了

3AC

#include<stdio.h>
#define eps 1e-4
double a[10010];
double b[10010];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        double p,q,r;
        scanf("%lf",&p);
        q=p*p+(1-p)*(1-p);
        r=1-q;
        double sum=0;
        a[0]=r;
        int i;
        for(i=1;i<=10000;i++)a[i]=a[i-1]*(i+1)/i*q;
        for(i=0;i<=10000;i++)sum+=2*a[i];
        printf("%.2lf\n",sum);
        }
    return 0;
    }

I題

bi=ai*w{mod m}

w*v=1{mod m}

so

bi*v=ai{mod m}

ai<<m

ai=bi*v%m

s=∑(bixi)

v*s=∑(bixi*v)=∑(aixi)

ai是個揹包

搞定

1WA於long long

2WA於%64d

3AC 改用cin

#include<stdio.h>
#define LL long long
#include<iostream>
using namespace std;
LL a[40],b[40],sum[40];
LL x[40];
int main(){
    LL n,v,m,w,S;
    int T;
    cin>>T;
    while(T--){
        cin>>n;
        int i,j;
        for(i=1;i<=n;i++)cin>>b[i];
        cin>>v>>m>>S;
        for(i=1;i<=n;i++)
        {
            a[i]=v*b[i];a[i]%=m;
            }
        int res=0;
        S*=v;S%=m;
        for(i=n;i>=1;i--){
            if(S>=a[i]){x[i]=1;S-=a[i];}
            else x[i]=0;
            }
        for(i=1;i<=n;i++)printf("%d",x[i]);
        printf("\n");
        }
    return 0;
    }

J

查克拉,dp什麼的

沒看懂提

MuQ~過的1Y

#include<stdio.h>
int main()
{
    long t,i,j,k,c,n,dp[10][10020],a[10020];
    scanf("%ld%ld",&c,&n);
    for(i=1;i<=n;i++)
       scanf("%ld",&a[i]);
    for(j=0;j<=n;j++)
       dp[0][j]=c;
    dp[1][0]=-1;
    for(j=1;j<=n;j++)
    {
       dp[1][j]=dp[1][j-1];
       if(dp[0][j]-a[j]>dp[1][j] && dp[0][j]!=-1)
          dp[1][j]=dp[0][j]-a[j];
    }
    dp[2][0]=-1;
    for(j=1;j<=n;j++)
    {
       dp[2][j]=dp[2][j-1];
       if(dp[1][j]+a[j]>dp[2][j] && dp[1][j]!=-1)
          dp[2][j]=dp[1][j]+a[j];
    }
    dp[3][0]=-1;
    for(j=1;j<=n;j++)
    {
       dp[3][j]=dp[3][j-1];
       if(dp[2][j]-a[j]>dp[3][j] && dp[2][j]!=-1)
          dp[3][j]=dp[2][j]-a[j];
    }
    dp[4][0]=-1;
    for(j=1;j<=n;j++)
    {
       dp[4][j]=dp[4][j-1];
       if(dp[3][j]+a[j]>dp[4][j] && dp[3][j]!=-1)
          dp[4][j]=dp[3][j]+a[j];
    }
    if(dp[4][n]==-1)printf("%ld\n",c);
    else printf("%d\n",dp[4][n]);
    return 0;
}

K題

矩陣快乘

普通遞推TLE

等價於a1s=1,a1j=0的列矩陣,不斷乘一個n*n的矩陣

快乘log

總時間

n^3log(m*k)*T

1WA於矩陣建錯了,和不是1

2WA,3WA忘記爲什麼了...

只記得有個trick,n=1

4AC

FB

#include<stdio.h>
double G[55][25][25];
double res[25][25];
double tm[25][25];
double aim[25],ha[25];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int i,j,l,p,n,m,K,k,s;
        scanf("%d%d%d%d",&n,&m,&K,&s);
        int tp=m*K;
        for(i=1;i<=n;i++)ha[i]=0;ha[s]=1;
        for(i=1;i<=n;i++)for(j=1;j<=n;j++){
            if(i==1&&j==2)G[0][j][i]=1.0;
            else if(i==n&&j==n-1)G[0][j][i]=1.0;
            else if(j==i+1||j==i-1)G[0][j][i]=0.5;
            else G[0][j][i]=0;
            res[i][j]=0;
            if(i==j)res[i][i]=1.0;
            }
        for(p=1;p<=50;p++){
            for(i=1;i<=n;i++)for(j=1;j<=n;j++){
                G[p][i][j]=0;
                for(k=1;k<=n;k++)G[p][i][j]+=G[p-1][i][k]*G[p-1][k][j];
                }
            }
        for(p=0;p<=50;p++){
            int flag=tp%2;tp/=2;
            if(!flag)continue;
            for(i=1;i<=n;i++)for(j=1;j<=n;j++)tm[i][j]=res[i][j];
            for(i=1;i<=n;i++)for(j=1;j<=n;j++){
                res[i][j]=0;
                for(k=1;k<=n;k++)res[i][j]+=G[p][i][k]*tm[k][j];
                }
            }
        for(i=1;i<=n;i++){
            aim[i]=0;
            for(k=1;k<=n;k++)aim[i]+=res[i][k]*ha[k];
            }
        for(i=1;i<=n;i++){
            if(n==1)aim[i]=1.0;
            if(i!=1)printf(" ");
            printf("%.4lf",aim[i]);
            }
        printf("\n");
        }
    return 0;
    }

L題

一個矩陣一條直線

計算幾何

MuQ~1Y

#include<stdio.h>
int main()
{
    double t,x1,x2,y1,y2,a,b,c,s;
    double i1,i2,j1,j2,j3,j0;
    double sum;
    scanf("%lf",&t);
    while(t--)
    {
       scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
       scanf("%lf%lf%lf",&a,&b,&c);
       s=(x2-x1)*(y2-y1);
       j0=(-1*a*x1-c)/b;
       j3=(-1*a*x2-c)/b;
       if(j0>=y2 && j3>=y2)
       {
          sum=0;
       }
       if(j0>=y2 && j3<=y2 && j3>=y1)
       {
          i1=(-1*b*y2-c)/a;
          sum=(x2-i1)*(y2-j3)/2;
       }
       if(j0>=y2 && j3<y1)
       {
          i1=(-1*b*y2-c)/a;
          i2=(-1*b*y1-c)/a;
          sum=(x2-i1+x2-i2)*(y2-y1)/2;
       }
       
       if(j0<y2 && j0>=y1 && j3>=y2)
       {
          i1=(-1*b*y2-c)/a;
          sum=(i1-x1)*(y2-j0)/2;
       }
       if(j0<y2 && j0>=y1 && j3<y2 && j3>=y1)
       {
          sum=(y2-j3+y2-j0)*(x2-x1)/2;
       }
       if(j0<y2 && j0>=y1 && j3<y1)
       {
          i1=(-1*b*y1-c)/a;
          sum=(j0-y1)*(i1-x1)/2;
       }
       
       if(j0<y1 && j3>=y2)
       {
          i1=(-1*b*y1-c)/a;
          i2=(-1*b*y2-c)/a;
          sum=(i1-x1+i2-x1)*(y2-y1)/2;
       }
       if(j0<y1 && j3<y2 && j3>=y1)
       {
          i1=(-1*b*y1-c)/a;
          sum=(x2-i1)*(j3-y1)/2;
       }
       if(j0<y1 && j3<y1)
       {
          sum=0;
       }
       
       if(sum>s/2)sum=s-sum;
       if(sum==0)sum=s;
       printf("%.3lf\n",sum);
    }
    return 0;
}



比賽小結

結果不錯(恩恩~~)

D拘束是字典樹不會,EG都TLE不太會剪枝

開局我不是很順,CE,RE都出了,不過後來踏下心來切概率還是不錯的

最不爽的就是尼瑪....電腦經常重啓...

貌似MuQ~狀態不錯

本場比賽概率||dp好多啊...

最後1h有隊伍過D

以爲是北航...

抓狂死...

繼續on my fighting way

還有感謝bnu某人的招待!!!

以上



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章