日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CodeForces - 616C 】The Labyrinth点石成金(并查集,dfs)

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CodeForces - 616C 】The Labyrinth点石成金(并查集,dfs) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

小O無意間發現了一張藏寶圖,它跟隨藏寶圖的指引來到了一個宮殿,宮殿的地板被分成了n*m塊格子,每個格子上放置了金子或者石頭

藏寶圖告訴小O,它可以選擇一塊石頭變成金子,并且帶走與變化后的金子聯通區域的所有金子(聯通指的是上下左右,不能斜著)

小O想計算一下點每個石頭能帶走的金子個數,幫幫他吧。

輸入:
第一行兩個數n,m (1 <= n,m <= 1000 )
隨后n行,每行m個字符,表示宮殿地板上放置的物品,' * '表示放置的是石頭,' . '表示放置的是金子

輸出:
在每個石頭位置輸出如果將該位置點石成金,能帶走的金子個數,方便起見,將這個數%10再輸出

輸入:
3 3
*.*
.*.
*.*
輸出:
3.3
.5.
3.3

輸入:
4 5
**..*
..***
.*.*.
*.*.*
輸出:
46..3
..732
.6.4.
5.4.3
?

Note

In first example, if we imagine that the central cell is empty then it will be included to component of size?5?(cross). If any of the corner cell will be empty then it will be included to component of size?3?(corner).

解題報告:

? 搜索上并查集就可以了。注意統計的時候,有可能重復,比如

這樣相同的答案會統計四次。所以要去重一下。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 1000 + 5; char maze[MAX][MAX]; int ans[MAX][MAX]; bool vis[MAX][MAX]; int f[MAX*MAX]; int num[MAX*MAX]; int n,m; int nx[4] = {0,1,0,-1}; int ny[4] = {1,0,-1,0}; int getf(int v) {return v == f[v] ? v : f[v] = getf(f[v]); } void merge(int u,int v) {int t1 = getf(u);int t2 = getf(v);f[t2] = t1; } int get(int x,int y) {return (x-1)*m +y; } void go(int x,int y) {for(int k = 0; k<4; k++) {int tx = x + nx[k];int ty = y + ny[k];if(tx < 1 || tx > n || ty < 1 || ty > m) continue;if(maze[tx][ty] == '*' || vis[tx][ty]) continue;merge(get(x,y),get(tx,ty));vis[tx][ty] = 1;go(tx,ty);} } int main() {cin>>n>>m;for(int i = 0; i<=n*m; i++) {f[i] = i;}for(int i = 1; i<=n; i++) {scanf("%s",maze[i]+1);}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(maze[i][j] == '.' && vis[i][j] == 0) {vis[i][j] = 1;go(i,j);} }}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(maze[i][j] == '*') continue;num[getf(get(i,j))]++;}}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(maze[i][j] == '.') ans[i][j] = '.';else {int cnt = 0;set<int> ss;for(int k = 0; k<4; k++) {int tx = i + nx[k];int ty = j + ny[k];if(maze[tx][ty] == '*')continue;if(tx < 1 || tx > n || ty < 1 || ty > m) continue;ss.insert(getf(get(tx,ty)));}auto it = ss.begin();for(;it!=ss.end();++it) cnt += num[*it];ans[i][j] = cnt;}}}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(maze[i][j] == '.') printf(".");else printf("%d",(ans[i][j]+1)%10);}puts("");}return 0 ; } /* 16:00-16:13 */ /* 4 1 * . * . */

別忘了這樣寫的話,每個入口都要加上vis[][]=1;(指的是main函數里)

題目不難,但是還是WA了一發,映射的時候注意是(x-1)*m而不是(x-1)*n。

總結

以上是生活随笔為你收集整理的【CodeForces - 616C 】The Labyrinth点石成金(并查集,dfs)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。