Skip to content
Logic Formatting

Logic Formatting

D. Kilani and the Game 解析(裸BFS、實作)

Posted on 2025 年 1 月 11 日 By jeff

Codeforce 1105 D. Kilani and the Game 解析(裸BFS、實作)

今天我們來看看CF1105D
題目連結

題目
給一個$n\times m$的地圖,地圖上有幾種格子:空地、路障、某個玩家的某些城堡。(可能有$1\le p\le9$個玩家)
給定一開始每個玩家至少有一個城堡,玩家照順序移動,每個玩家有自己的移動步數,求最後每個玩家能有幾個城堡。

前言

寫這題一直TLE,搞了好幾個小時才發現如果每次BFS都宣告一個新的queue,那麼可能會因為allocation的cost太大而TLE,並且還有一些其他的奇怪問題(此處不提)。總之,我們應該極力避免頻繁declare queue。

想法

顯然就是BFS,但是實作上要注意:queue中存的是${vertex,剩下的步數}$,由於我們每回合開始的時候,一定會有一些點在queue裡(上回合遺留下來的,實作上我們每回合結束時把沒有移動步數的格子放入全域變數等下回合push進queue裡),我們要同時防止其他玩家走到這一點,又要讓擁有這個格子的玩家在自己的回合時不會判斷這個格子不能走,我們有兩種實作方式:

  1. 在push入新格子進queue之前先把格子標示為$visited$,BFS從新格子開始時就不要檢查是否走過了(也就是只在往外走時檢查是否走過)。 這種方法可以某種程度上縮減queue中多餘的元素數量,是比較好的方法。
  2. push入queue時還不會標為$visited$。每次從新的格子開始BFS時,除非這個格子的移動數量$>0$,否則不要標記為$visited$(但是地圖上已經寫上去了)。 這種方法比較糟糕,沒什麼結構。

程式碼(法1):

const int _n=1010;  
struct ele{int x,y,move;};  
int t,n,m,s[11],p,mp[_n][_n],ans[11];  
int dx[4]={-1,1,0,0};  
int dy[4]={0,0,-1,1};  
queue<ele> st[11],q;  
bool vis[_n][_n];  
char c,a[_n][_n];  
main(void) {  
  scanf("%d%d%d",&n,&m,&p); rep(i,1,p+1)scanf("%d",&s[i]);  
  rep(i,1,n+1)scanf("%s",a[i]+1);  
  rep(i,1,n+1)rep(j,1,m+1){  
    c=a[i][j];int res=c;if(c=='.')res='0'+0;if(c=='#')res='0'+10;  
    mp[i][j]=res-'0';  
    if(mp[i][j]!=0 and mp[i][j]!=10)st[mp[i][j]].push({i,j,s[mp[i][j]]}),vis[i][j]=1;   if(mp[i][j]==10)vis[i][j]=1;  
  }  
  while(1){  
    bool OUT=1;rep(i,1,p+1){if(!st[i].empty())OUT=0;}  
    if(OUT)break;  
    rep(id,1,p+1){  
      while(!st[id].empty())q.push(st[id].front()),st[id].pop();  
      ele now;int nx,ny;  
      while(!q.empty()){  
        now=q.front(); q.pop();  
        int x=now.x,y=now.y,mv=now.move;  
        mp[x][y]=id;  
        if(mv==0)st[id].push({x,y,s[id]});  
        else rep(j,0,4){  
          nx=x+dx[j],ny=y+dy[j];  
          if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny]||mp[nx][ny]||mv<=0)continue;  
          vis[nx][ny]=1;  
          q.push({nx,ny,mv-1});  
        }  
      }  
    }  
  }  
  rep(i,1,n+1)rep(j,1,m+1)ans[mp[i][j]]++;  
  rep(i,1,p+1)printf("%d ",ans[i]);  
  return 0;  
}  

標頭、模板請點Submission看
Submission

程式碼(法2):

const int _n=1010;  
struct ele{int x,y,move;};  
int t,n,m,s[20],p,mp[_n][_n],ans[20];  
queue<ele> st[20],q;  
bool vis[_n][_n];  
char c;  
main(void) {cin.tie(0);ios_base::sync_with_stdio(0);  
  cin>>n>>m>>p;rep(i,1,p+1)cin>>s[i];  
  cin.get();rep(i,1,n+1){rep(j,1,m+1){  
    c=cin.get();int res=c;if(c=='.')res='0'+0;if(c=='#')res='0'+10;  
    mp[i][j]=res-'0';  
    assert(mp[i][j]<11);  
    if(mp[i][j]!=0 and mp[i][j]!=10)st[mp[i][j]].push({i,j,s[mp[i][j]]});  
    if(mp[i][j]==10)vis[i][j]=1;  
  }cin.get();}  
  rep(i,0,n+1)mp[i][0]=10; rep(i,0,m+1)mp[0][i]=10;  
  rep(i,0,n+1)mp[i][m+1]=10; rep(i,0,m+1)mp[n+1][i]=10;  
  while(1){  
    bool OUT=1;rep(i,1,p+1){assert(i<11);if(!st[i].empty())OUT=0;}  
    if(OUT)break;  
    rep(id,1,p+1){  
      assert(id<11);  
      while(!st[id].empty())q.push(st[id].front()),st[id].pop();  
      while(!q.empty()){  
        ele now=q.front(); q.pop();  
        if(vis[now.x][now.y])continue;  
        int x=now.x,y=now.y,mv=now.move;  
        mp[x][y]=id; if(mv>0)vis[x][y]=1;  
        if(mv==0)st[id].push({x,y,s[id]});  
        if(mv>0 and !mp[x-1][y])q.push({x-1,y,mv-1});  
        if(mv>0 and !mp[x+1][y])q.push({x+1,y,mv-1});  
        if(mv>0 and !mp[x][y-1])q.push({x,y-1,mv-1});  
        if(mv>0 and !mp[x][y+1])q.push({x,y+1,mv-1});  
      }  
    }  
  }  
  rep(i,1,n+1)rep(j,1,m+1)ans[mp[i][j]]++;  
  rep(i,1,p+1)cout<<ans[i]<<' '; cout<<'\n';  
  return 0;  
}  

標頭、模板請點Submission看
Submission

ojcode codeforceojcode實作裸BFS

文章導覽

Previous post
Next post

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

近期文章

  • B. Kyoya and Permutation 解析(思維、數論、DP)
  • G. Guess One Character 解析(思維)
  • E. The Road to Berland is Paved With Good Intentions 解析(思維、2-SAT、SCC、拓樸排序)
  • E. Xor-sequences 解析(思維、矩陣快速冪)
  • LeetCode. First Missing Positive 解析(思維)

近期留言

尚無留言可供顯示。

彙整

  • 2025 年 2 月
  • 2025 年 1 月

分類

  • ojcode
©2026 Logic Formatting | WordPress Theme by SuperbThemes