题目描述
众所周知,LOL这款伟大的游戏,有个叫盖伦的英雄。他的伟大之处在于他特别喜欢蹲草丛阴人。某日,德玛西亚与诺克萨斯之间又发生了一场战斗,嘉文四世希望盖伦能带领一支K人的德玛西亚军队出战。
战斗发生在召唤师峡谷。整个召唤师峡谷被分割成M行N列的一个矩阵,矩阵中有空地和几片草丛。这几片草丛中有些很大、有些很小。一个1×1的草丛能容纳3个士兵,盖伦坚信蹲草偷袭战术能战胜诺克萨斯军队,所以他希望他的军队能全部蹲进草丛里。当然,为了不影响盖伦的作战,盖伦需要单独霸占连起来的一片草丛(不管草丛有多大)。
输入
第一行M、N、K,表示矩阵的行数、列数和士兵数量。
接下来M行,输入矩阵,'.'代表平地,'*'代表草丛。
接下来M行,输入矩阵,'.'代表平地,'*'代表草丛。
输出
如果德玛西亚军队和盖伦都能躲进草丛里,则输出“Demacia Win!”,否则输出“Demacia Lose!”
样例输入
3 3 6
.**
...
.*.
样例输出
Demacia Win!
提示
1<=m、n<=500
1<=k<=50000
这里对于两个1×1的草丛是否连在一起的定义是:对于每个1×1的草从,它与周围(上下左右)的草丛是连在一起的。
dfs方法
import java.util.*;
public class Main {
static Scanner in=new Scanner(System.in);
static int m,n,k,sum=0,minGrass=Integer.MAX_VALUE,cnt;
static String[] a = new String[505];
static char[][] matrix = new char[505][505];
static int[][] bool = new int[505][505];
static int[][] dir ={
{0,1},
{1,0},
{0,-1},
{-1,0}
};
static int dfs(int x,int y){
int tx,ty,min=Integer.MAX_VALUE;
//四个方向都要尝试一遍
for (int i = 0; i < 4; i++) {
tx=0;ty=0;
tx=x+dir[i][0];
ty=y+dir[i][1];
//越界处理
if(tx>=m||ty>=n||tx<0||ty<0)
continue;
if(matrix[tx][ty]=='*'){
matrix[tx][ty]='.';//标记走过的
sum++;//所能连起来的计数
dfs(tx,ty);
}
}
if(sum<min)
min=sum;
return min;
}
public static void main(String[] args) {
m= in.nextInt();
n= in.nextInt();
k=in.nextInt();
for (int i = 0; i < m; i++)
a[i]=in.next();
//对输入进行处理转化为二维数组方便处理
for (int i = 0; i < m; i++) {
for (int j = 0; j < a[i].length(); j++){
matrix[i][j]=a[i].charAt(j);
if(matrix[i][j]=='*'){//统计总的草丛数目
cnt++;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n ; j++){
if(matrix[i][j]=='*'){
sum=1;//一开始的那个进行计数
matrix[i][j]='.';//对每个草丛进行深搜,搜索过的 要进行去除(标记)
minGrass=Math.min(dfs(i,j),minGrass);//取最小值
//System.out.println(sum+" "+minGrass);
}
}
}
cnt-=minGrass; //减去艾伦霸占的一片
if(cnt*3>=k)
System.out.println("Demacia Win!");
else
System.out.println("Demacia Lose!");
}
}
bfs方法:
import java.util.*;
public class Main {
static Scanner in=new Scanner(System.in);
static int m,n,k,sum=0,minGrass=Integer.MAX_VALUE,cnt;
static String[] a = new String[505];
static char[][] matrix = new char[505][505];
static int[][] bool = new int[505][505];
static int[][] dir ={
{0,1},
{1,0},
{0,-1},
{-1,0}
};
static int bfs(Queue<node> q){
int tx,ty,min=Integer.MAX_VALUE;
while(!q.isEmpty()){
//四个方向都要尝试一遍
for (int i = 0; i < 4; i++) {
tx=0;ty=0;
tx=q.peek().x+dir[i][0];
ty=q.peek().y+dir[i][1];
//越界处理
if(tx>=m||ty>=n||tx<0||ty<0)
continue;
if(matrix[tx][ty]=='*'){
matrix[tx][ty]='.';//标记走过的
sum++;//所能连起来的计数
node n= new node();
n.x=tx;
n.y=ty;
q.add(n);
}
}
q.poll();
}
if(sum<min)
min=sum;
return min;
}
public static void main(String[] args) {
Queue<node> q = new LinkedList<node>();
m= in.nextInt();
n= in.nextInt();
k=in.nextInt();
for (int i = 0; i < m; i++)
a[i]=in.next();
//对输入进行处理转化为二维数组方便处理
for (int i = 0; i < m; i++) {
for (int j = 0; j < a[i].length(); j++){
matrix[i][j]=a[i].charAt(j);
if(matrix[i][j]=='*'){//统计总的草丛数目
cnt++;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n ; j++){
if(matrix[i][j]=='*'){
sum=1;//一开始的那个进行计数
matrix[i][j]='.';//对每个草丛进行深搜,搜索过的 要进行去除(标记)
node n= new node();
n.x=i;
n.y=j;
q.add(n);
minGrass=Math.min(bfs(q),minGrass);//取最小值
System.out.println(sum+" "+minGrass);
}
}
}
cnt-=minGrass; //减去艾伦霸占的一片
if(cnt*3>=k)
System.out.println("Demacia Win!");
else
System.out.println("Demacia Lose!");
}
}
class node{
int x;
int y;
}
分析:题目意思就是寻找一片能连起来的最小的草丛让艾伦填上,然后把士兵放在有草丛的点即可
我一开始还以为士兵也要连着。。。读题读题啊,那么使用dfs或者bfs统计一片能连起来的最小的草丛,然后用总的草丛数目减去再*3如果大于等于k,就是win,否则lose