https://www.acmicpc.net/problem/14500
ㅗㅓㅏㅜ모양을 제외한 블럭들은 상하좌우방향으로 탐색을 4번까지 하면 구해진다.
그러므로, ㅗㅓㅏㅜ모양과 일반적인 블럭들을 따로 처리해주었다.
[JAVA}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N,M,ans=0;
static int[][] map;
static boolean[][] visit;
static int[] dx= {0,0,1,-1};
static int[] dy= {1,-1,0,0};
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(br.readLine()," ");
N=Integer.parseInt(st.nextToken());
M=Integer.parseInt(st.nextToken());
map=new int[N][M];
visit=new boolean[N][M];
for(int i=0; i<N; i++) {
st=new StringTokenizer(br.readLine()," ");
for(int j=0; j<M; j++) {
map[i][j]=Integer.parseInt(st.nextToken());
}
}//입력끝
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
visit[i][j]=true;
dfs(i,j,1,map[i][j]);
visit[i][j]=false;
unusual(i,j);
}
}
System.out.println(ans);
}
private static void unusual(int x, int y) {
if((x==0&&y==0) ||(x==0&&y==M-1) || (x==N-1&&y==0) || (x==N-1 &&y==M-1))
return;
int cnt=1;
int total=map[x][y];
for(int i=0; i<4; i++) {
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<0||ny<0||nx>=N||ny>=M) continue;
cnt++;
total+=map[nx][ny];
}
if(cnt==4) {
if(ans<total)ans=total;
}else if(cnt==5) {
for(int i=0; i<4; i++) {
int nx=x+dx[i];
int ny=y+dy[i];
int tmp=total-map[nx][ny];
if(ans<tmp) ans=tmp;
}
}
}
private static void dfs(int x, int y, int cnt, int sum) {
if(cnt==4) {
if(ans<sum)ans=sum;
return;
}
for(int i=0; i<4; i++) {
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<0||ny<0||nx>=N||ny>=M||visit[nx][ny]==true)continue;
visit[nx][ny]=true;
dfs(nx,ny,cnt+1,sum+map[nx][ny]);
visit[nx][ny]=false;
}
}
}
[C++]
#include <iostream>
#include <algorithm>
using namespace std;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int N,M;
int map[500][500];
int ans=0;
bool visited[500][500]={0,};
//일반적인 경우 (ㅗ모양 제외한 경우)
void DFS(int x, int y, int depth, int sum){
if(depth==4){
if(ans < sum) ans = sum;
return;
}
visited[x][y]=1;
for(int i=0; i<4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx<0 || ny<0 || nx>=N || ny>=M || visited[nx][ny]) continue;
DFS(nx,ny,depth+1,sum+map[nx][ny]);
}
visited[x][y]=0;
}
//ㅗ의 경우 ( 4방향 모두 더한 값에서 제일작은칸의 값 빼서 ㅗ ㅏ ㅜ ㅓ 중 가장 큰 값구함
void SpCase(int x, int y, int sum){
int cnt=0;//범위 벗어난 횟수 카운트하기위한 변수
int minVal=10000;
for(int i=0; i<4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx<0 || ny<0 || nx>=N || ny>=M){
cnt++; continue;//범위 벗어난 수 카운트하기
}
sum+=map[nx][ny];
minVal = min(minVal, map[nx][ny]);
}
if(cnt>1) return;//범위 2번이상 벗어나면 ㅗ모양이 안되서 리턴
if(cnt==1){//범위 1번만 벗어난 경우: ㅗ모양이기 떄문에 최솟값 뺄 필요없음
ans = max(ans,sum);
}
if(cnt==0){//4방향 모두더한 경우 :값이 제일 작은 칸빼기
ans = max(ans,sum-minVal);
}
}
int main(){
cin >> N >> M;
for(int i=0; i<N; i++){
for(int j=0; j<M; j++){
cin >> map[i][j];
}
}
//일반적인 경우
for(int i=0; i<N; i++){
for(int j=0; j<M; j++){
DFS(i, j, 1, map[i][j]);
}
}
//ㅗ모양 탐색
for(int i=0; i<N; i++)for(int j=0; j<M; j++){
SpCase(i,j, map[i][j]);
}
cout << ans;
return 0;
}
댓글