728x90
이 문제의 경우 주사위를 움직이는 dice_move 함수와 연속해서 이동할 수 있는 칸의 수를 리턴하는 C 함수인 두 가지 함수로 쪼갤 수 있습니다.
첫 번째 함수인 dice_move 함수는 상하좌우로 주사위가 이동할 때 주사위 전개도에서 숫자가 이동하는 것을 구현했습니다. 두 번째 함수인 C 함수는 해당 칸에서 얼마나 연속해서 이동할 수 있는지 계산해야 하므로 deque 또는 queue를 사용하거나 dfs로 구현할 수 있습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
#define endl '\n'; | |
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); | |
using namespace std; | |
typedef long long ll; | |
typedef unsigned long long ull; | |
typedef pair<int,int> pii; | |
typedef pair<int,ll> pil; | |
const int INF=1e9; | |
int dx[]={0,1,0,-1}, dy[]={1,0,-1,0}; | |
vector<vector<int>> dice={{0,2,0},{4,1,3},{0,5,0},{0,6,0}}; | |
void dice_move(int didx) { | |
// 주사위 이동 | |
if(didx==0 || didx==2) { | |
deque<int> temp={dice[1][0],dice[1][1],dice[1][2],dice[3][1]}; | |
if(didx==0) { | |
int a=temp.back(); | |
temp.pop_back(); | |
temp.push_front(a); | |
} | |
else { | |
int a=temp.front(); | |
temp.pop_front();temp.push_back(a); | |
} | |
dice[1][0]=temp[0]; | |
dice[1][1]=temp[1]; | |
dice[1][2]=temp[2]; | |
dice[3][1]=temp[3]; | |
} | |
else { | |
deque<int> temp={dice[0][1],dice[1][1],dice[2][1],dice[3][1]}; | |
if(didx==1) { | |
int a=temp.back(); | |
temp.pop_back(); | |
temp.push_front(a); | |
} | |
else { | |
int a=temp.front(); | |
temp.pop_front(); | |
temp.push_back(a); | |
} | |
dice[0][1]=temp[0]; | |
dice[1][1]=temp[1]; | |
dice[2][1]=temp[2]; | |
dice[3][1]=temp[3]; | |
} | |
return; | |
} | |
int C(int x, int y, vector<vector<int>>& v) { | |
// 연속적으로 이동가능한 칸의 수를 리턴하는 함수 | |
vector<vector<int>> visit(v.size(),vector<int>(v[0].size())); | |
visit[x][y]=1; | |
deque<pii> dq={{x,y}}; | |
int target=v[x][y]; | |
int ret=1; | |
while(!dq.empty()) { | |
auto [a,b]=dq.front(); | |
dq.pop_front(); | |
for(int i=0;i<4;i++) { | |
int nx=a+dx[i], ny=b+dy[i]; | |
if(nx>=0 && nx<v.size() && ny>=0 && ny<v[0].size()) { | |
if(!visit[nx][ny] && v[nx][ny]==target) { | |
dq.push_back({nx,ny}); | |
visit[nx][ny]=1; | |
ret++; | |
} | |
} | |
} | |
} | |
return ret; | |
} | |
int main() { | |
fastio | |
//freopen("input.txt","r",stdin); | |
int n,m,k; cin>>n>>m>>k; | |
vector<vector<int>> v(n,vector<int>(m)); | |
for(int i=0;i<n;i++) for(auto& it : v[i]) cin>>it; | |
int x=0,y=0,didx=0; | |
int ans=0; | |
while(k--) { | |
int nx=x+dx[didx], ny=y+dy[didx]; | |
if(nx>=0 && nx<n && ny>=0 && ny<m) { | |
dice_move(didx); | |
x=nx, y=ny; | |
} | |
else { | |
didx=didx+2<4 ? didx+2 : (didx+2)%4; | |
nx=x+dx[didx], ny=y+dy[didx]; | |
dice_move(didx); | |
x=nx, y=ny; | |
} | |
ans+=v[x][y]*C(x,y,v); | |
// 시계 또는 반시계 회전에 따라 주사위 상하좌우 결정 | |
if(dice[3][1]>v[x][y]) didx=didx==3 ? 0 : didx+1; | |
else if(dice[3][1]<v[x][y]) didx=didx==0 ? 3 : didx-1; | |
} | |
cout<<ans; | |
return 0; | |
} |
728x90