牛客练习赛31
A.地、颜色、魔法
题目描述
现在,你作为一名新星鹏洛客,找到了一块绝佳的修炼地。这块地方可以被描述成一个 n x m 的矩形。你已经在这块地中的一些位置打好了标记。接下去,就该对整块地赋予你的颜色了。一个位置能被赋予你的颜色,当且仅当满足以下条件之一:
1. 这个位置被打上了标记。
2. 这个位置在不经过被打标记的位置的情况下与边界不连通(这个图是四联通的)。换句话说,如果你从这个位置开始,在不经过被打标记的位置,且只能向上下左右四个方向移动的情况下永远不能走到地图的边界,那么这个位置符合条件。
现在,你的好基友想知道,你能为多少个位置赋予你自己的颜色呢?
1. 这个位置被打上了标记。
2. 这个位置在不经过被打标记的位置的情况下与边界不连通(这个图是四联通的)。换句话说,如果你从这个位置开始,在不经过被打标记的位置,且只能向上下左右四个方向移动的情况下永远不能走到地图的边界,那么这个位置符合条件。
现在,你的好基友想知道,你能为多少个位置赋予你自己的颜色呢?
输入描述:
第一行包含两个正整数 n, m ,表示地图的长和宽。
接下去 n 行,每行一个长为 m 的字符串,表示地图的一行。
其中 '.'表示该位置未被打标记;'#'表示该位置被打了标记。保证地图仅由'.'和'#'构成。
输出描述:
输出仅一行,包含一个整数,表示你的答案。
示例1
输入
4 4 .... .### .#.# .###
输出
9
说明
可以被赋予颜色的位置在下图中用 标出了。
备注:
1 ≤ n x m ≤ 10^6.
解题思路:题意就是当前坐标没有被打标记即'.',如果其一路沿着'.'能到达四周任意边界,那么就不能将其标记为'#',否则将其标记为'#',问最终被标记的数量。显然,我们只需对四周边界的每一个坐标点进行一次dfs,同时记录边界中每个'.'能达到的最远总距离step,则最终的答案为n*m-step。还有一点,要用vector存图,避免超内存。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn=1e6+5; 5 int n,m,step;bool vis[maxn]; 6 vector<string> vec;string str; 7 int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}}; 8 void dfs(int a,int b){ 9 if(a<0||b<0||a>=n||b>=m||vis[a*m+b]||vec[a][b]=='#')return; 10 vis[a*m+b]=true,step++,vec[a][b]='#'; 11 for(int i=0;i<4;++i)dfs(a+dir[i][0],b+dir[i][1]); 12 } 13 int main(){ 14 while(cin>>n>>m){ 15 vec.clear(),step=0;memset(vis,false,sizeof(vis)); 16 for(int i=0;i<n;++i)cin>>str,vec.push_back(str); 17 for(int j=0;j<m;++j){ 18 if(vec[0][j]=='.')dfs(0,j); 19 if(vec[n-1][j]=='.')dfs(n-1,j); 20 } 21 for(int i=1;i<n-1;++i){ 22 if(vec[i][0]=='.')dfs(i,0); 23 if(vec[i][m-1]=='.')dfs(i,m-1); 24 } 25 cout<<n*m-step<<endl; 26 } 27 return 0; 28 }
B.赞迪卡之声妮莎与奥札奇
题目描述
奥札奇军团降临!赞迪卡陷入危机!无尽轮回钨拉莫和真理屠夫寇基雷带领着这群庞大的掠食者在赞迪卡肆意破坏。旅法师妮莎瑞文必须要阻止这一切。
在赞迪卡时空的一角,有 n 个寇族的部落。为了抵御奥札奇的进攻,这些部落之间联系密切。在任意两个部落之间都有一条直接道路相连接。换句话说,这 n 个部落与若干条道路构成了一张完全图。
现在,奥札奇军团已经占领了 1 号寇族部落并停留在此处。而钨拉莫与寇基雷两王却开始了游戏(伊莫库大姐快来管管)。游戏的规则是这样的:钨拉莫与寇基雷两王轮流带领奥札奇军团移动一次。每次可以从一个寇族部落通过一条未被腐蚀的道路移动到另一个寇族部落。任何移动必须在这 n 个寇族部落及其道路中进行。由于奥札奇对法术力的吞噬,奥札奇军团行经的道路都会被腐蚀。最后,在规则的限制下,奥札奇军团将无路可走。此时,将带领军团进行下一步移动的奥札奇之王将输掉这个游戏。钨拉莫先手。
钨拉莫与寇基雷作为奥札奇三祖中的两者,自然拥有超高的智力。所以你可以认为,他们都将以最优决策进行游戏。
游戏的赢家将率领军队与妮莎作战,而妮莎还在赶来的路上。所以请你先观察这个游戏,到时便可以告诉妮莎谁会是她的对手。
输入描述:
本题有多组测试数据。
第一行一个正整数 T ,表示数据组数。
接下去 T 行,每行一个数 n ,表示寇族部落的个数。
输出描述:
输出共 T 行,每行一个字符串 "Ulamog, the Infinite Gyre" 或 "Kozilek, Butcher of Truth" 表示胜利者(去掉括号)。前者为无尽轮回钨拉莫,后者为真理屠夫寇基雷。
示例1
输入
2 1 3
输出
Kozilek, Butcher of Truth Ulamog, the Infinite Gyre
说明
- 当 n=3 时,钨拉莫可以率领军团从 1 走到 2 ,之后 的边不能再走了。
- 下一步寇基雷只能带领军团移动至 3 ,之后 的边不能再走了。
- 最后钨拉莫只要将军团移回 1 ,寇基雷就无路可走了。
备注:
1 ≤ T ≤ 2000
1 ≤ n ≤ 2000
解题思路:枚举+验证,枚举前几个n可以发现,在两者都采取最优策略的前提下,只有当n=1时,先手必败,其余情况为先手必胜,验证交一发AC。下面是题解:
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int T,n; 4 int main(){ 5 while(cin>>T){ 6 while(T--){ 7 cin>>n; 8 if(n==1)cout<<"Kozilek, Butcher of Truth"<<endl; 9 else cout<<"Ulamog, the Infinite Gyre"<<endl; 10 } 11 } 12 return 0; 13 }