728x90
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
int n, t, k;
//0,1,
int dx[] = {-1,-1,0,1,1,1,0,-1};
int dy[] = {0,1,1,1,0,-1,-1,-1};
struct info {
int r;
int c;
int m;
int d;
int s;
};
info nothing = { 0,0,0,0,0 };
void print(vector<info>&infoList) { //test
for (int i = 0; i < infoList.size(); i++) {
cout << infoList[i].r << " " << infoList[i].c << " " <<"m:"<< infoList[i].m <<" "<<"d:"<<infoList[i].d<< " "<<"s:"<<infoList[i].s<<endl;;
}
}
void move(vector<info>&infoList) {
vector<info>arr[51][51]; // 2차원 배열에 여러 요소를 넣을 때 이러한 자료구조를 쓴다.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
arr[i][j].clear();
}
}
int nr, nc;
for (int i = 0; i < infoList.size(); i++) {
info ifo = infoList[i];
nr = ifo.r;
nc = ifo.c;
arr[nr][nc].push_back(ifo); // 이동할 위치를 정했으면 arr에 집어 넣어준다.
}
infoList.clear();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (arr[i][j].size() == 1) { // i, j 위치에 한개가 있을 때
infoList.push_back(arr[i][j].front());
continue;
}
else if (arr[i][j].size() > 1) { //i,j 위치에 1개보다 더 많을 때
int m = 0;
int s = 0;
for (int l = 0; l < arr[i][j].size(); l++){
m += arr[i][j][l].m; // (i,j) 위치에 질량들을 모두 더한다
s += arr[i][j][l].s; // (i,j) 위치에 속도들을 모두 더한다.
}
m /= 5; // 질량 모두 더하고 5로 나눈다.
s /= (arr[i][j].size()); // 속력 모두 더하고 해당 위치에 있는 크기만큼 나눈다.
if (m == 0) { continue; }
vector<info>dir = arr[i][j];
bool toggle = false;
int idx = 0;
while (idx<dir.size() && ((dir[idx].d % 2)==0)) { // (i,j) 위치의 모든 방향이 2로 나누어떨어지는지확인
idx++;
}
if (idx == dir.size()) { toggle = true; }
idx = 0;
while (idx<dir.size() && ((dir[idx].d % 2) != 0)) { // (i,j) 위치의 모든 방향이 2로 안 나누어떨어지는지확인
idx++;
}
if (idx == dir.size()) { toggle = true; }
int d = 0;
if (toggle == false) { // 모두 2로 나누어 떨어지거나 모두 2로 안나누어 떨어지거나 할때
for (int p = 0; p< 4; p++) {
d = 1 + p * 2;
infoList.push_back({i,j,m,d,s});
}
}
else { // 그 외
for (int p = 0; p < 4; p++) {
d = p * 2;
infoList.push_back({ i, j, m, d, s });
}
}
}
}
}
}
bool cango(int x, int y) {
return x >= 0 && x < n && y >= 0 && y < n;
}
void simulate(vector<info>&infoList) {
for (int i = 0; i < infoList.size(); i++) {
info ifo = infoList[i];
int r = ifo.r;
int c = ifo.c;
int m = ifo.m;
int d = ifo.d;
int s = ifo.s;
int nr, nc;
nr = (r + dx[d]*s)%n; // 1행은 n-1행과
nc = (c + dy[d]*s)%n; // 1열은 n-1열과 연결이 되어 있으므로 %를 한다.
if (cango(nr, nc)){
infoList[i] = { nr,nc,m,d,s };
}
else {
if (nr < 0) {
nr = nr + n; // -1 행이면 3행이 되도록
}
if (nc < 0) {
nc += n; // -1 열이면 3열이 되도록
}
infoList[i] = { nr,nc,m,d,s }; // 이동한 좌표와 정보를 리스트에 저장
}
}
move(infoList); //움직이기 시작한다.
}
int main() {
cin >> n; //격자수
cin >> t; //파이어볼개수
cin >> k; //명령수
int r;
int c;
int m;
int d;
int s;
vector<info>infoList;
for (int i = 0; i < t; i++) {
cin>> r; //x
cin>> c; //y
cin>> m; //질량
cin>> s; //속력
cin>> d; //방향
infoList.push_back({ r-1,c-1,m,d,s });
}
for (int i = 0; i < k; i++) {
simulate(infoList);
}
int totalweight = 0;
for (int i = 0; i < infoList.size(); i++) {
totalweight += infoList[i].m;
}
cout << totalweight << endl;
}
<Java>
package Samsung;
import java.io.*;
import java.util.*;
public class 마법사상어와파이어볼 {
static int dx[] = {-1,-1,0,1,1,1,0,-1};
static int dy[] = {0,1,1,1,0,-1,-1,-1};
static int n,m,k;
static ArrayList<Ball>[][] map;
static StringTokenizer st;
public static class Ball{
int r,c,m,d,s;
public Ball(int r, int c, int m, int s, int d) {
super();
this.r = r;
this.c = c;
this.m = m;
this.d = d;
this.s = s;
}
}
public static boolean cango(int x , int y) {
return x>=1 && x<=n && y>=1 && y<=n;
}
public static int getAllsum(ArrayList<Ball>ballInfos) {
int sum =0;
for(int i=0; i<ballInfos.size(); i++) { //ballInfos 안에 있는 모든 무게를 더해준다.
sum += ballInfos.get(i).m;
}
return sum;
}
//ballinfos를 움직인 결과를 map에 넣고 map에서는 움직인 결과들을 계산해서 다시 ballInfos에 넣어주고 k가 0이 될 때까지 반복한다.
public static void simulate(ArrayList<Ball>ballInfos) {
for(int t=0; t<k; t++) { //상어들을 k만큼 움직여준다
for(int i=0; i<ballInfos.size(); i++) {
int r = ballInfos.get(i).r;
int c = ballInfos.get(i).c;
int m = ballInfos.get(i).m;
int d = ballInfos.get(i).d;
int s = ballInfos.get(i).s;
int ns = s;
int nr = r;
int nc = c;
while(ns>0) {
nr += dx[d];
nc += dy[d];
if(!cango(nr,nc)) { /*어려웠던점1: 범위를 벗어났을때 연결된 행 or 열로 바꿔주는 것 -> 문제 제대로 안읽어서 이조건 고려 안함*/
if(nr==0) {nr=n;} //만약 0 이되면 1행과 n행과 연결이 되어있으므로 nr을 n으로 바꿔준다.
if(nr==n+1) {nr=1;} //만약 n+1이되면 n행과 1행이 연결도이어 있으므로 nr을 1로 바꿔준다.
if(nc==0) {nc=n;}
if(nc==n+1) {nc=1;}
}
ns--; //속도 거리만큼 빼준다.
}
map[nr][nc].add(new Ball(nr,nc,m,s,d)); //움직인 결과를 map에다가 넣어준다.
}
ballInfos.clear(); //기존에 있던 파이어볼 정보는 지운다.
for(int i=1; i<=n; i++) { //map 을 탐색하면서 파이어볼이 있는 곳을 찾는다
for(int j=1; j<=n; j++) {
if(!map[i][j].isEmpty() && map[i][j].size()>=2) { //한칸에 여러개의 파이어볼이 있을 때
int summ=0;
int sums=0;
boolean tg = true; //모두 짝 or 홀: true
boolean prev = false;//홀수 false, 짝수 true
ArrayList<Ball>arr = map[i][j];
int sz = arr.size();
for(int p=0; p<arr.size(); p++) {
summ += arr.get(p).m; //질량을 모두 더해준다.
sums += arr.get(p).s; //속력을 모두 더해준다.
int dir = arr.get(p).d; //방향을 얻어온다
//어려웠던점2: 모든 파이어볼의 방향이 홀수인지 짝수 인지 알아내는것
if(p==0) {
prev = ((dir%2)==0); //이전 방향을 현재방향으로 바꿔주고 반복문 다시 시작
}
else {
if(dir%2==0 && prev==false) { //현재 방향이짝수 인데 이전 방향은 홀수 인 경우
tg=false;
}
else if(dir%2!=0 && prev==true) { //현재 방향이 홀수 인데 이전 방향은 짝수인 경우
tg=false;
}
prev = ((dir%2)==0); //이전 방향을 현재방향으로 바꿔주고 반복문 다시 시작
}
}
if(tg) { //모두 짝수 or 홀수 일때
if((summ/5) !=0) {
ballInfos.add(new Ball(i,j,summ/5,sums/sz,0)); //ballInfos에 저장해준다.
ballInfos.add(new Ball(i,j,summ/5,sums/sz,2));
ballInfos.add(new Ball(i,j,summ/5,sums/sz,4));
ballInfos.add(new Ball(i,j,summ/5,sums/sz,6));
}
}
else { //모두 짝수 or 홀수 아닐때
if((summ/5) !=0) {
ballInfos.add(new Ball(i,j,summ/5,sums/sz,1));
ballInfos.add(new Ball(i,j,summ/5,sums/sz,3));
ballInfos.add(new Ball(i,j,summ/5,sums/sz,5));
ballInfos.add(new Ball(i,j,summ/5,sums/sz,7));
}
}
map[i][j].clear(); //있던 파이어볼 지워준다.
}
else if(!map[i][j].isEmpty() && map[i][j].size()==1) { //해당 좌표에 있는 파이어볼이 한개일때
if(map[i][j].get(0).m!=0) {
ballInfos.add(map[i][j].get(0));
}
map[i][j].clear();
}
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
ArrayList<Ball>ballInfos= new ArrayList<>();
map = new ArrayList[n+1][n+1];
for(int i=0; i<=n; i++) {
for(int j=0; j<=n; j++) {
map[i][j]=new ArrayList<>();
}
}
for(int i=0; i<m; i++) {
st = new StringTokenizer(br.readLine());
ballInfos.add(new Ball(Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken())));
//현재 파이어볼의 정보를 ballInfos에 저장
}
simulate(ballInfos); //파이어볼정보로 시뮬레이션
int ans = getAllsum(ballInfos); //시뮬레이션 한 결과 무게 총합을 반환
System.out.println(ans);
}
}
어려웠던점1: 범위를 벗어났을때 연결된 행 or 열로 바꿔주는 것 -> 문제 제대로 안읽어서 이조건 고려 안함
어려웠던점2: 모든 파이어볼의 방향이 홀수인지 짝수 인지 알아내는것
'백준 > 삼성기출' 카테고리의 다른 글
스타트택시 - 1923번(Java) (0) | 2021.09.18 |
---|---|
어른상어 - 19237번 (JAVA) (0) | 2021.09.16 |
큐빙 (0) | 2021.04.19 |
치킨 배달 (0) | 2021.04.19 |
드래곤 커브 (0) | 2021.04.18 |