zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/carcar/p/10792265.html
Copyright © 2011-2022 走看看