• codeforces gym #102082C Emergency Evacuation(贪心Orz)


    题目链接:

    https://codeforces.com/gym/102082

    题意:

    在一个客车里面有$r$排座位,每排座位有$2s$个座位,中间一条走廊

    有$p$个人在车内,求出所有人走出客车的最短时间

    数据范围:

     $1leq rleq 500$

     $1leq sleq 500$

    $1leq pleq 2sp$

    分析: 

     一道全场题,居然想了三个小时,我也是醉了。

    解法一:模拟每秒他们的动作。如果有多个人下一秒要走向同一个位置,他们任何一个人走上去都行。重点是,这样的复杂度是$O(s^2n^2)$,但是可以发现在1000秒以后,他们所有的人一定紧贴着。所以以后每秒走出一个人,也就是说,可以停止模拟,直接得到答案(这是我比赛的时候想到的)

    解法二:逆处理(orz),想让他们都出去,然后一个一个的放进去。所有的阻挡都在入口了。算出每个人就位的最长时间

    解法三:算出每个人出来的时间(无人阻挡),然后每秒出去一个人,如果同一秒有多人,那么任意一个人出去,其它的人加在下一秒

    ac代码:

    解法一:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=500+10;
    const int maxm=1e7+10;
    const int mod=1e9+7;
    int r,s,p,ans;
    int ma[maxn][2*maxn];
    
    void mov()
    {
        if(ma[r][s+1])ma[r][s+1]=0,p--;
        for(int i=r;i>=1;i--)
        {
            if(ma[i][s+1]&&ma[i+1][s+1]==0)ma[i+1][s+1]=1,ma[i][s+1]=0;
            for(int j=s;j>=1;j--)
                if(ma[i][j+1]==0&&ma[i][j])ma[i][j]=0,ma[i][j+1]=1;
            for(int j=s+2;j<=2*s+1;j++)
                if(ma[i][j-1]==0&&ma[i][j])ma[i][j-1]=1,ma[i][j]=0;
        }
    }
    int main()
    {
        scanf("%d %d %d",&r,&s,&p);
        for(int i=1;i<=p;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(y>s)y++;
            ma[x][y]=1;
        }
        while(p)
        {
            ans++;
            mov();
            if(ans>=1000)break;
        }
        printf("%d
    ",ans+p);
        return 0;
    }
    

    解法二:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=500+10;
    const int maxm=1e7+10;
    const int mod=1e9+7;
    int r,s,p,ans;
    int num[maxn*maxn*2];
    int main()
    {
        scanf("%d %d %d",&r,&s,&p);
        for(int i=1;i<=p;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(y>s)y++;
            num[i]=abs(s+1-y)+abs(r+1-x);
            //cout<<num[i]<<endl;
        }
        sort(num+1,num+1+p);
        int ans=0;
        for(int i=p;i>=1;i--)
            ans=max(p-i+num[i],ans);
        cout<<ans<<endl;
        return 0;
    }
    

    解法三:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=500+10;
    const int maxm=1e7+10;
    const int mod=1e9+7;
    int r,s,p,ans;
    int num[maxn*maxn*2];
    int main()
    {
        scanf("%d %d %d",&r,&s,&p);
        for(int i=1;i<=p;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(y>s)y++;
            num[abs(s+1-y)+abs(r+1-x)]++;
            //cout<<num[i]<<endl;
        }
    //    sort(num+1,num+1+p);
        int ans=0;
        for(int i=1;i<maxn*maxn*2;i++)
        {
            if(num[i])
                ans=max(i,ans);
            if(num[i]>=2)num[i+1]+=num[i]-1;
        }
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    DELPHI 画报表 画表头 stringgrid控件
    蜂巢 Thinking in Agile 我们需要怎样的软件过程(1)
    小博一周年了 将开源进行到底
    Windows Mobile下实现图片的3D效果
    蜂巢 Thinking in Agile 我们需要怎样的软件过程(2)
    Windows 中各种 dll 的导出功能
    以下代码中的两个sizeof用法有问题吗?
    sizeof和strlen
    以下反向遍历array数组的方法有什么错误?
    找错题
  • 原文地址:https://www.cnblogs.com/carcar/p/10792265.html
Copyright © 2020-2023  润新知