* 각 원자 객체들을 이동시켜야 하고, 동일 위치에 여러 객체가 겹칠 수 있다는 점 

= '마법사 상어와 파이어볼' 문제와 비슷. 거기에 문제 유형 정리해두겠음

goldenriver42.tistory.com/79?category=976583

 

 

SWEA 5648 원자 소멸 시뮬레이션

N (<= 1,000)개의 원자가 데카르트 좌표계에 놓여있다.

처음 좌표 범위는 -1,000 <= x, y <= 1,000,

한 타임에 한 칸씩 움직이며, 방향은 0 (y 증가), 1 (y 감소), 2 (x 감소), 3 (x 증가)

0원자들의 움직임을 시뮬레이션 해서, 부딪칠때마다 방출되는 에너지의 합을 구하는 문제.

 

문제점)

1. Negative coordinates on Cartesian coordinate system
→ 그냥 음수만 모두 양수로 바뀌게 1000 더해주고, y좌표가 커지는 방향(0)을 W로 잡는게 편함.
비슷하게 dir = 1은 E, 2는 N, 3은 S로 잡기. 


2. 원자가 움직인 후의 좌표에, 아직 움직이지 않은 다른 원자가 있는 경우, 한 칸에 여러 개의 원자가 겹치는 경우
→ '마법사 상어와 파이어볼' 문제와 동일한 문제.
배열 등으로 살아있는 원자 관리하고, 매 시뮬레이션 마다 움직인 후의 좌표를 board에 찍는 방법이
가장 깔끔한 정공법.

 

배열 복사 등에 너무 인색하지 말자!

이게 가장 간단한 방법이고, 더 꼬인 다른 방법으로 구현하면 시간 잡아먹음.

const int SIZ = 4001;
int board[SIZ][SIZ];
vector<atom> v;

void simulation_once(){
    // 1. v의 원자들 move후 board에 표시
    
    // 2. 겹친 원자들 처리
    // ex) (x,y)에 겹친 원자 개수 표시, 혹은 에너지 합 표시
    
    // 3. 살아남은 원자들만 v에 업데이트 해주고, board 초기화
    // tmp 배열 써서 살아있는 원자들만 빼온 후, 다시 v에 push_back
}


3. 중간에 부딪히는 경우 (아이디어)

모든 좌표를 2배 사전 처리해주면, 중간에서 만나는 경우가 사라짐.

코드가 가장 깔끔해지고, 따로 체크를 안하게 되기에 시간도 절약하는 방법임.

 

아니면, 원자 A가 움직이기 전, 해당 방향에 방향만 정반대인 다른 원자가 있는지 확인하면 되는데,

이거 따지면 시간 엄청 늘어나서 코드 꼬이고 TLE 무조건 남.

+ Recent posts