這道題的解法感受仍是不少的,寫完後看了看題解,發現這道題模擬多是最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; }