第十三届北京师范大学程序设计竞赛(6+2/10)

来源:互联网 发布:C 释放动态数组内存 编辑:程序博客网 时间:2024/05/29 17:13
  1. A Araleii & Bill的冠名权争夺战之登顶校赛

————————————————————————————————————————————
我们这样考虑

对于一个说对的概率是1/m ,那么n个人的期望就是n/m

然而这个期望其实就是

                        E=n/m=∑i=1n(pi×i)(p_i为i个人答对的概率)

pn最大值显然是 n/m=pn×n
所以最后答案就是1/m

这个我当时并不知道这个公式,只是觉得如果我们都能看到对方的帽子的话我只要安排m种颜色的帽子,每个帽子1-m,m+1-m+m…..到n即可。最后得出结论 1/m

B 神奇的身高
————————————————————————————————————————————
队友过得,后期我自己补的他们过的部分题
对于一个序列我们将其变成升序序列,可以直接 a[i]-i 然后求LIS. 但是这样的结果可能是负数或者0的,
然而其实很简单 对于每个a[i]-i 如果小于0 那就一定要变化,所以就对剩下的序列求LIS就可以了,求得的结果就是不用修改的,那么修改的就是n减去
附本题代码

#include <bits/stdc++.h>using namespace std;typedef long long int LL;const int N   = 100000+7;const int INF = 2000000007;int b[N],cnt,n;int main(){    while(~scanf("%d",&n)){        int mx=0,x;cnt=0;        for(int i=0;i<=n;i++) b[i]=INF;        for(int i=1,id;i<=n;i++){            scanf("%d",&x);x-=i;            if(x<0) continue;            id = upper_bound(b+1,b+1+n,x)-b;            b[id]=x;            mx=mx>id?mx:id;        }        printf("%d\n",n-mx);    }    return 0;}

——————————————————————————————————————————

C Attack on Titan
队友过得,自己不会- -

————————————————————————————————————————————

D 超级线段树
队友过的,我无耻的把代码和思路复制过来了
————————————————————————————————————————————
这个题简直666 啊

本质就是一个区间覆盖问题,
但是直接区间覆盖会TLE ,然后就一直想怎么做到O(n),,,最后GG了

其实我们可以逆序覆盖,然后每次更新的时候lazy_tag如果有,那就不给它更新了,算是上一个大剪枝了.

附本题代码
————————————————————————————————————————————

#include <bits/stdc++.h>using namespace std;typedef long long int LL;const int N = 1e6+7;inline int read(){    int x=0,f=1;char ch = getchar();    while('0'> ch||ch> '9') {if(ch=='-')f=-1;ch=getchar();}    while('0'<=ch&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}    return x*f;}int lazy[N<<2];inline void build(int rt,int l,int r){    lazy[rt]=0;    if(l==r)return;    int m = r+l >> 1;    build(rt<<1  ,l  ,m);    build(rt<<1|1,m+1,r);}inline void pushdown(int &rt){    if(lazy[rt]){        if(!lazy[rt<<1])  lazy[rt<<1]  =lazy[rt];        if(!lazy[rt<<1|1])lazy[rt<<1|1]=lazy[rt];    }}inline void update(int rt,int l,int r,int &L,int &R,int &val){    if(lazy[rt]) return ;    if(L<=l&&r<=R){        lazy[rt]=val;        return;    }    pushdown(rt);    int m = r+l >> 1;    if(L<=m) update(rt<<1  ,l  ,m,L,R,val);    if(R> m) update(rt<<1|1,m+1,r,L,R,val);}inline void visit(int rt,int l,int r){    if(l==r){printf("%d\n",lazy[rt]);return;}    pushdown(rt);    int m = r+l >> 1;    visit(rt<<1  ,l  ,m);    visit(rt<<1|1,m+1,r);}int l[N],r[N],p[N];int main(){    int _=read(),n,m;    while(_--){        n=read(),m=read();        build(1,1,n);        for(int i=1;i<=m;i++)   l[i]=read(),r[i]=read(),p[i]=read();        for(int i=m;i;i--)      update(1,1,n,l[i],r[i],p[i]);        visit(1,1,n);    }    return 0;}

E rating计算

————————————————————————————————————————————
签到水题,不解释

F 进化之地(Evoland)

————————————————————————————————————————————
当时队友A的,我后期补的

bfs + 细节,注意很多地方,还有就是加一维表示当前地图是几维地图,之后细节判断即可。

#include <bits/stdc++.h>#define maxs 202020#define mme(i,j) memset(i,j,sizeof(i))using namespace std;int way[5]= {1,0,-1,0};            int wax[5]= {0,1,0,-1};char maps[102][102];int n,m,sx,sy;int ans;bool vis[102][102][5];struct node{    int x,y;    int step;    int state;} now,nex;void bfs(int x,int y)// 2-3D{    mme(vis,0);    now.x=x;    now.y=y;    now.state=2;    now.step=0;    vis[now.x][now.y][now.state]=1;    queue<node>q;    q.push(now);    node tp;    while(!q.empty())    {        now=q.front();        q.pop();        if(maps[now.x][now.y]=='1')        {            printf("%d\n",now.step);            return;        }        for(int i=0; i<4; i++)        {            nex.x=now.x+wax[i];            nex.y=now.y+way[i];            nex.step=now.step+1;            if(nex.x>0&&nex.x<=n&&nex.y>0&&nex.y<=m)            {                if(maps[nex.x][nex.y]=='.'||maps[nex.x][nex.y]=='0'||maps[nex.x][nex.y]=='1')                {                    nex.state=now.state;                    if(vis[nex.x][nex.y][nex.state]==0)                    {                        vis[nex.x][nex.y][nex.state]=1;                        q.push(nex);                    }                }                if(maps[nex.x][nex.y]=='#')continue;                if(maps[nex.x][nex.y]=='@')                {                    nex.state=now.state;                    if(vis[nex.x][nex.y][nex.state]==0)                    {                        vis[nex.x][nex.y][nex.state]=1;                        q.push(nex);                    }                    nex.state=5-now.state;                    if(vis[nex.x][nex.y][nex.state]==0)                    {                        vis[nex.x][nex.y][nex.state]=1;                        q.push(nex);                    }                }                if(maps[nex.x][nex.y] == '2') {                    if(now.state==2) {                        nex.state=now.state;                        if(vis[ nex.x ][ nex.y ][ nex.state ] == 0) {                            vis[ nex.x ][ nex.y ][ nex.state ] = 1;                            q.push( nex );                        }                    }                    else                        continue;                }                if(maps[nex.x][nex.y]=='3'){                    if(now.state==3){                        nex.state=now.state;                        if(vis[nex.x][nex.y][nex.state]==0){                        vis[nex.x][nex.y][nex.state]=1;                        q.push(nex);                        }                    }                    else                        continue;                }            }        }    }    printf("-1\n");    return;}void Solve(){    ans=-1;    sx=sy=-1;    scanf("%d %d",&n,&m);    for(int i=1; i<=n; i++)scanf("%s",maps[i]+1);    for(int i=1; i<=n; i++)    {        for(int j=1; j<=m; j++)        {            if(maps[i][j]=='0')            {                sx=i;                sy=j;                break;            }        }        if(sx!=-1)            break;    }    if(sx==-1)    {        puts("-1");       return;    }    bfs(sx,sy);    return;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        Solve();    }    return 0;}

————————————————————————————————————————————

G 贪心

————————————————————————————————————————————
没什么说的直接二分答案就好了
赛后补的题
————————————————————————————————————————————

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define ll long long intstruct node{    ll x,y,ss;}a[150000];ll n,m;ll cmp(node a,node b){    return a.ss<b.ss;}int Slove(ll mid){    ll sum=0;    for(ll j=1;j<=n;j++)a[j].ss=mid*a[j].y+a[j].x;    sort(a+1,a+1+n,cmp);    for(ll j=1;j<=mid;j++)    {        sum+=a[j].ss;    }    if(sum<=m)return 1;    else return 0;}int main(){    while(~scanf("%lld%lld",&n,&m))    {        ll output=0;        for(ll i=1;i<=n;i++)scanf("%lld",&a[i].x);        for(ll i=1;i<=n;i++)scanf("%lld",&a[i].y);        ll l=0;        ll r=n;        while(r-l>=0)        {            ll mid=(l+r)/2;            if(Slove(mid)==1)            {                output=mid;                l=mid+1;            }            else r=mid-1;        }        printf("%lld\n",output);    }}

————————————————————————————————————————————

H 简单的传球游戏

————————————————————————————————————————————
队友过得

I 打怪兽

————————————————————————————————————————————

K 最长上升子序列(这个未补完)

————————————————

————————————————————————————

0 0
原创粉丝点击