Emergency Evacuation 模擬了一下

題目連接 找不到


分析

這道題的解法感受仍是不少的,寫完後看了看題解,發現這道題模擬多是最low的算法了,什麼貪心啊,BFS啊,都能解決這個問題,然而我就用的模擬,模擬大法好,不會別的,首先直接模擬的話複雜度最差大約\(O(250,000,000,000)\),顯然不是咱們想要的,再仔細觀察,由於這個門,一次只能出一我的,那麼當人不少時,屢次移動人以後必定會形成一個現象————人擠成一堆了,這時就能夠保證一個步數就能讓一我的出去,因此須要步數就是當前還剩的人,大概多少步後會成爲這個現象呢?不是很好找,但能夠保證這個步數在1000步之內,由於橫着數兩塊每塊最多有500,豎着也最多500,因此當步數大於1000時直接跳出循環就好了,這麼作的時間複雜度大概在\(O(100000000)\)左右,時限3s,能夠A掉。ios

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int pre[N][N];
int main(){
    int r,s,p;
    cin>>r>>s>>p;
    for(int i=1;i<=p;i++){
        int a,b;
        cin>>a>>b;
        if(b>s)b++;
        pre[a][b]=1;
    }
    int ans=0,k=s<<1|1;
    while(p){
        ans++;
        if(pre[r][s+1])pre[r][s+1]=0,p--;
        for(int i=r;i;i--){
            if(pre[i][s+1]&&pre[i+1][s+1]==0)swap(pre[i][s+1],pre[i+1][s+1]);
            for(int j=s;j;j--)
                if(pre[i][j]&&pre[i][j+1]==0)swap(pre[i][j],pre[i][j+1]);
            for(int j=s+2;j<=k;j++)
                if(pre[i][j]&&pre[i][j-1]==0)swap(pre[i][j],pre[i][j-1]);    
        }
        if(ans>=N)break;
    }
    cout<<ans+p;
}
相關文章
相關標籤/搜索