題目描述
衆所周知,LOL這款偉大的遊戲,有個叫蓋倫的英雄。他的偉大之處在於他特別喜歡蹲草叢陰人。某日,德瑪西亞與諾克薩斯之間又發生了一場戰鬥,嘉文四世希望蓋倫能帶領一支K人的德瑪西亞軍隊出戰。
戰鬥發生在召喚師峽谷。整個召喚師峽谷被分割成M行N列的一個矩陣,矩陣中有空地和幾片草叢。這幾片草叢中有些很大、有些很小。一個1×1的草叢能容納3個士兵,蓋倫堅信蹲草偷襲戰術能戰勝諾克薩斯軍隊,所以他希望他的軍隊能全部蹲進草叢裏。當然,爲了不影響蓋倫的作戰,蓋倫需要單獨霸佔連起來的一片草叢(不管草叢有多大)。
輸入
接下來M行,輸入矩陣,'.'代表平地,'*'代表草叢。
輸出
樣例輸入
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