Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16-mjj111 #229

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

16-mjj111 #229

wants to merge 1 commit into from

Conversation

mjj111
Copy link
Collaborator

@mjj111 mjj111 commented Sep 24, 2024

πŸ”— 문제 링크

λ£¨λŒν”„μ˜ λ°˜λž€

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

3μ‹œκ°„...

✨ μˆ˜λ„ μ½”λ“œ

ν•΄λ‹Ή λ¬Έμ œλŠ” 주어진 방식에 맞좰 λ£¨λŒν”„λ₯Ό 움직이고,
산타λ₯Ό 움직인 λ’€,
μ‚΄μ•„μžˆλŠ” μ‚°νƒ€μ—κ²Œ 점수 μƒμŠΉμ„ μ‹œμΌœ
결과적으둜 각 산타가 μ μˆ˜κ°€ μ–Όλ§ˆμžˆλŠ”μ§€ 좜λ ₯ν•˜λ©΄ λ©λ‹ˆλ‹€.

while santas.has_living() and turn < m:
    turn += 1
    rudolph.move(santas, board, turn)
    santas.move(rudolph, board, turn)
    santas.alive_plus()
santas.print_points()

λ£¨λŒν”„κ°€ 움직일 λ•ŒλŠ” λ£¨λŒν”„μ™€ μ‚°νƒ€κ°„μ˜ 거리가 가깝고, xμ’Œν‘œκ°€ 크고 yμ’Œν‘œκ°€ 큰 순으둜
졜적의 산타λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.

def move(self, santas, board, turn):
        santa = santas.get_clost(self.x, self.y)

λ£¨λŒν”„κ°€ 산타λ₯Ό ν–₯ν•΄ λŒμ§„ν•˜λŠ”λ° λ§Œμ•½ λΆ€λ”ͺν˜”λ‹€λ©΄ μ—°μ‡„μ μœΌλ‘œ μ‚°νƒ€λŠ” ν•œ μΉΈμ”© λ°€λ €λ‚˜μ•Όν•©λ‹ˆλ‹€.

            else:
                santas.check(santa, board, self.dx[direction], self.dy[direction])

λ°€λ €λ‚œ μ‚°νƒ€λŠ” μžμ‹ μ΄ λ–¨μ–΄μ§ˆ μœ„μΉ˜μ— μ‘΄μž¬ν•  산타λ₯Ό ν•œ μΉΈμ”© μž¬κ·€λ₯Ό 톡해 λ°€μ–΄μ€λ‹ˆλ‹€.

def check(self, santa, board, move_x, move_y) :
        if board[santa.x][santa.y] == 0:
            board[santa.x][santa.y] = santa.number
            return 
        
        located_santa = self.santa_dict[board[santa.x][santa.y]]
        board[santa.x][santa.y] = santa.number

        located_santa.x += move_x
        located_santa.y += move_y 

        if is_out(located_santa.x, located_santa.y):
            located_santa.is_out = True
            return 

        self.check(located_santa, board, move_x, move_y) 

μ‚°νƒ€μ˜ μ›€μ§μž„μ€ 쑰금 λ³΅μž‘ν•©λ‹ˆλ‹€.
μ‚°νƒ€μ˜ μˆœλ²ˆλŒ€λ‘œ μ ‘κ·Όν•˜μ—¬ μ›€μ§μ΄λ˜, λ§Œμ•½ κΈ°μ ˆν•œ μƒνƒœκ±°λ‚˜ μž₯외일 경우 움직이지 λͺ»ν•©λ‹ˆλ‹€.

        for santa in self.santa_list:
            if santa.is_out or santa.is_sturned >= turn:
                continue

ν˜„μž¬ 산타λ₯Ό κΈ°μ€€μœΌλ‘œ λ£¨λŒν”„λ₯Ό ν–₯ν•΄ 갈 수 μžˆλŠ” 졜적의 λ°©ν–₯으둜 μ›€μ§μž…λ‹ˆλ‹€.

def move(self, rudolph, board, turn):
            ...
            now_distance = get_distance(santa.x, santa.y, rudolph.x, rudolph.y)
            best_distance = now_distance
            best_move = None

            for i in range(4):
                next_x = santa.x + self.dx[i]
                next_y = santa.y + self.dy[i]

                if is_out(next_x, next_y) or board[next_x][next_y] >= 1:
                    continue

                next_distance = get_distance(next_x, next_y, rudolph.x, rudolph.y)
                if next_distance < best_distance:
                    best_distance = next_distance
                    best_move = (next_x, next_y, i)

            if best_move:
                next_x, next_y, direction = best_move
                board[santa.x][santa.y] = 0
                santa.x, santa.y = next_x, next_y

                if board[next_x][next_y] == 0:  
                    board[santa.x][santa.y] = santa.number

λ§Œμ•½ 산타가 움직이닀가 λ£¨λŒν”„λ₯Ό λ§Œλ‚ κ²¨μš° μ‚°νƒ€μ˜ 힘만큼 λ‹€μ‹œ λ’€λ‘œ λ¬ΌλŸ¬λ‚˜ 지며,
λ¬ΌλŸ¬λ‚˜μ§ˆλ•Œ, λ‹€λ₯Έ 산타가 있으면 λ„λ―Έλ…Έμ²˜λŸΌ ν•œ μΉΈμ”© λ°€λ¦½λ‹ˆλ‹€.

               ....
                elif board[next_x][next_y] == -1:
                    santa.point += self.power 
                    santa.is_sturned = turn + 1

                    direction = (direction + 2) % 4 
                    move_x, move_y = self.dx[direction], self.dy[direction]

                    next_x = santa.x + move_x * self.power 
                    next_y = santa.y + move_y * self.power 
                    
                    if is_out(next_x, next_y) :
                        santa.is_out = True 
                        continue 

                    santa.x, santa.y = next_x, next_y
                    self.check(santa, board, move_x, move_y)

각 턴이 끝날 λ•Œλ§ˆλ‹€, μž₯내에 μžˆλŠ” μ‚°νƒ€λŠ” 점수λ₯Ό νšλ“ν•©λ‹ˆλ‹€.

def alive_plus(self):
        for santa in self.santa_list:
            if not santa.is_out: 
                santa.point += 1

이후 각 μ‚°νƒ€μ˜ 점수λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€..

def print_points(self):
        for santa in self.santa_list:
            print(santa.point, end = " ")

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

이 μ •λ„μ˜ λΉ‘κ΅¬ν˜„μ€, 일단 μ„€κ³„ν•˜κ³  κ΅¬ν˜„ν•œλ’€μ—
ν•˜λ‚˜μ”© κ²°κ³Όλ₯Ό 좜λ ₯ν•΄μ„œ λ””λ²„κΉ…ν•˜λŠ” λ°©ν–₯으둜 진행해야할 κ²ƒκ°™μŠ΅λ‹ˆλ‹€.

κ΅¬ν˜„ ν›„ 결과값을 λΉ„κ΅ν–ˆλŠ”λ° 틀리면,
λΉ‘κ΅¬ν˜„ λ¬Έμ œλŠ” κ΅¬ν˜„μ΄ λ³΅μž‘ν•΄μ„œ 디버깅이 μ–΄λ €μš°λ―€λ‘œ
μ€‘κ°„λ§ˆλ‹€ 확인할 수 있게 κ΅¬ν˜„μ„ λΆ„λ¦¬ν•˜λ©΄ 쒋을 것 κ°™μ•„μš” πŸ€”

Copy link
Collaborator

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2μ‹œκ°„ λ°•κ³  GG μ³€μŠ΅λ‹ˆλ‹€..
λͺ…μ€€λ‹˜ μ½”λ“œ 보고 κ°ˆμ•„μ—Žμ—ˆλŠ”λ°λ„ μ•ˆλ˜λ„€μš” γ…œ
λ‚˜μ€‘μ— μž¬λ„μ „ ν•˜κ² μŠ΅λ‹ˆλ‹€...

ν‹€λ¦° 전체 μ½”λ“œ

#include <iostream>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>

using namespace std;

constexpr int MAX_DISTANCE = 2500;
const vector<pair<int, int>> SantaOffset{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
const vector<pair<int, int>> RudolphOffset{{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};

inline int GetDistanceBetween(int r1, int c1, int r2, int c2)
{
    return (r1 - r2) * (r1 - r2) + (c1 - c2) * (c1 - c2);
}

struct FSanta
{
    int Power;
    int Number;
    int R, C;
    bool bOut;
    int Score;
    int StunnedTurn;

    FSanta(int InPower, int InNumber, int InR, int InC)
    : Power(InPower)
    , Number(InNumber)
    , R(InR)
    , C(InC)
    , bOut(false)
    , Score(0)
    , StunnedTurn(0)
    {}
};

struct FRudolph
{
    int Power;
    int R, C;
    
    FRudolph(int InPower, int InR, int InC)
    : Power(InPower)
    , R(InR)
    , C(InC)
    {}
};

int N, M, P, C, D;
vector<vector<int>> Board;
FRudolph* Rudolph;
vector<FSanta*> SantaList;
unordered_map<int, FSanta*> SantaMap;

inline bool OutOfBound(int r, int c)
{
    return !(1 <= r && r <= N && 1 <= c && c <= N);
}

inline bool bAllSantasOut()
{
    for(const FSanta* Santa : SantaList)
    {
        if(false == Santa->bOut)
        {
            return false;
        }
    }

    return true;
}

void Interaction(FSanta* InSanta, const int dr, const int dc)
{
    if(Board[InSanta->R][InSanta->C] == 0)
    {
        Board[InSanta->R][InSanta->C] = InSanta->Number;
        return;
    }

    FSanta* Santa = SantaMap[Board[InSanta->R][InSanta->C]];
    Board[InSanta->R][InSanta->C] = InSanta->Number;

    Santa->R += dr;
    Santa->C += dc;

    if(OutOfBound(Santa->R, Santa->C))
    {
        Santa->bOut = true;
        return;
    }

    Interaction(Santa, dr, dc);
}

FSanta* GetNearestSanta()
{
    vector<FSanta*> Candidates;
    int NearestDistance = MAX_DISTANCE;

    for(FSanta* Santa : SantaList)
    {
        if(Santa->bOut)
        {
            continue;
        }

        int Distance = GetDistanceBetween(Rudolph->R, Rudolph->C, Santa->R, Santa->C);
        if(Distance < NearestDistance)
        {
            Candidates.clear();
            NearestDistance = Distance;
            Candidates.emplace_back(Santa);
        }
        else if(Distance == NearestDistance)
        {
            Candidates.emplace_back(Santa);
        }
    }

    sort(Candidates.begin(), Candidates.end(),
    [&](const FSanta* Lhs, const FSanta* Rhs)
    {
        if(Lhs->R == Rhs->R) return Lhs->C > Rhs->C;
        return Lhs->R > Rhs->R;
    });

    return Candidates.front();
}

void MoveRudolph(int InTurn)
{
    FSanta* NearestSanta = GetNearestSanta();
    int NearestDistance = MAX_DISTANCE;
    int NearestDirection = -1;

    for(int Dir = 0; Dir < RudolphOffset.size(); ++Dir)
    {
        int nr = Rudolph->R + RudolphOffset[Dir].first;
        int nc = Rudolph->C + RudolphOffset[Dir].second;

        if(OutOfBound(nr, nc))
        {
            continue;
        }

        int Distance = GetDistanceBetween(nr, nc, NearestSanta->R, NearestSanta->C);
        if(Distance < NearestDistance)
        {
            NearestDirection = Dir;
            NearestDistance = Distance;
        }
    }

    int nr = Rudolph->R + RudolphOffset[NearestDirection].first;
    int nc = Rudolph->C + RudolphOffset[NearestDirection].second;
    
    Board[Rudolph->R][Rudolph->C] = 0;
    Rudolph->R = nr, Rudolph->C = nc;
    Board[Rudolph->R][Rudolph->C] = -1;

    if(nr == NearestSanta->R && nc == NearestSanta->C)
    {
        NearestSanta->Score += Rudolph->Power;
        NearestSanta->StunnedTurn = InTurn;
        NearestSanta->R += RudolphOffset[NearestDirection].first * Rudolph->Power;
        NearestSanta->C += RudolphOffset[NearestDirection].second * Rudolph->Power;

        if(OutOfBound(NearestSanta->R, NearestSanta->C))
        {
            NearestSanta->bOut = true;
        }
        else
        {
            Interaction(NearestSanta, RudolphOffset[NearestDirection].first, RudolphOffset[NearestDirection].second);
        }
    }
}

void MoveSanta(int InTurn)
{
    for(FSanta* Santa : SantaList)
    {
        if(Santa->bOut || InTurn < Santa->StunnedTurn + 2)
        {
            continue;
        }

        int NearestDistance = GetDistanceBetween(Rudolph->R, Rudolph->C, Santa->R, Santa->C);
        int NearestDirection = -1;
        for(int Dir = 0; Dir < SantaOffset.size(); ++Dir)
        {
            int nr = Santa->R + SantaOffset[Dir].first;
            int nc = Santa->C + SantaOffset[Dir].second;
            
            if(OutOfBound(nr, nc) || Board[nr][nc] >= 1)
            {
                continue;
            }

            int Distance = GetDistanceBetween(Rudolph->R, Rudolph->C, nr, nc);
            if(Distance < NearestDistance)
            {
                NearestDistance = Distance;
                NearestDirection = Dir;
            }
        }

        if(NearestDirection == -1)
        {
            continue;
        }

        int nr = Santa->R + SantaOffset[NearestDirection].first;
        int nc = Santa->C + SantaOffset[NearestDirection].second;

        Board[nr][nc] = 0;
        Santa->R = nr, Santa->C = nc;
        if(Board[nr][nc] == 0)
        {
            Board[nr][nc] = Santa->Number;
        }
        else if(Board[nr][nc] == -1)
        {
            Santa->Score += Santa->Power;
            Santa->StunnedTurn = InTurn;

            int Reverse = (NearestDirection + 2) % 4;
            int dr = SantaOffset[Reverse].first;
            int dc = SantaOffset[Reverse].second;

            nr = Santa->R + dr * Santa->Power;
            nc = Santa->C + dc * Santa->Power;

            if(OutOfBound(nr, nc))
            {
                Santa->bOut = true;
            }
            else
            {
                Santa->R = nr;
                Santa->C = nc;
                Interaction(Santa, dr, dc);
            }
        }
    }
}

int main() 
{
    cin.tie(nullptr)->sync_with_stdio(false);
    
    cin >> N >> M >> P >> C >> D;

    int Rr, Rc; cin >> Rr >> Rc;

    Rudolph = new FRudolph(C, Rr, Rc);

    Board.assign(N + 1, vector<int>(N + 1, 0));
    Board[Rr][Rc] = -1;

    for(int i = 0; i < P; ++i)
    {
        int Pn, Sr, Sc; cin >> Pn >> Sr >> Sc;
        Board[Sr][Sc] = Pn;

        FSanta* Santa = new FSanta(D, Pn, Sr, Sc);
        SantaList.push_back(Santa);
        SantaMap[Pn] = Santa;
    }

    sort(SantaList.begin(), SantaList.end(),
    [&](const FSanta* Lhs, const FSanta* Rhs)
    {
        return Lhs->Number < Rhs->Number;
    });

    for(int Turn = 1; false == bAllSantasOut() && Turn <= M; ++Turn)
    {
        MoveRudolph(Turn);
        MoveSanta(Turn);
        for(FSanta* Santa : SantaList)
        {
            if(false == Santa->bOut)
            {
                Santa->Score++;
            }
        }
    }

    for(const FSanta* Santa : SantaList)
    {
        cout << Santa->Score << " ";
    }

    return 0;
}

@mjj111
Copy link
Collaborator Author

mjj111 commented Oct 2, 2024

2μ‹œκ°„ λ°•κ³  GG μ³€μŠ΅λ‹ˆλ‹€.. λͺ…μ€€λ‹˜ μ½”λ“œ 보고 κ°ˆμ•„μ—Žμ—ˆλŠ”λ°λ„ μ•ˆλ˜λ„€μš” γ…œ λ‚˜μ€‘μ— μž¬λ„μ „ ν•˜κ² μŠ΅λ‹ˆλ‹€...

ν‹€λ¦° 전체 μ½”λ“œ

μ½”λ“œ λ³΄λ‹ˆκΉŒ 맀 μ°¨ μ›€μ§μ΄λŠ”κ±° print ν•΄μ„œ λ””λ²„κΉ…ν•˜λ©΄, μΆ”κ°€ 1μ‹œκ°„μ•ˆμ— ν‘Έμ‹€κ±° κ°™μ€λ°μš”..?

Copy link
Member

@gjsk132 gjsk132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λ£¨λŒν”„ 머리 깨질 것 κ°™μ•„μš”.... κ·Έλ§Œν• λž˜μš”...γ…œγ… γ… 

μΆ©λŒμ΄λž‘ μƒν˜Έμž‘μš©ν•˜λŠ”λ°μ„œ, λ£¨λŒν”„κ°€ λͺ©ν‘œλ₯Ό μ €ν•œν…Œλ‘œ λŒλ ΈλŠ”μ§€ 죽을 것 κ°™μ•„μ„œ, ν¬κΈ°ν–ˆμŠ΄λ‹ˆλ‹€.πŸ₯²

포기...

input = open("input.txt").readline

size, turn, santa_alive, r_force, s_force = map(int,input().split())

r_x, r_y = map(int,input().split())
limit = float('inf')

s_offset = [(-1,0), (0, 1), (1, 0), (0, -1)]

santa_poses = [0]*santa_alive

# 0 : alive / 1: stun / 2 : dead
santa_status = [0]*santa_alive

santa_score = [0]*santa_alive

for _ in range(santa_alive):
    s_num, s_x, s_y = map(int,input().split())
    santa_poses[s_num-1] = [s_x, s_y]

def rudolph_move(r_x, r_y):
    nearest_idx = 0
    n_x, n_y = 0, 0
    min_dist = limit

    for idx, pos in enumerate(santa_poses):
        sx, sy = pos
        dist = pow((r_x-sx), 2) + pow((r_y-sy), 2)

        if dist > min_dist:
            continue
        elif dist == min_dist:
            if sx < n_x:
                continue
            
            if sx == n_x and sy < n_y:
                continue
        
        min_dist = dist
        n_x, n_y = sx, sy
        nearest_idx = idx

    force = [0, 0]

    if r_x > santa_poses[nearest_idx][0]:
        r_x -= 1
        force[0] -= 1
    elif r_x < santa_poses[nearest_idx][0]:
        r_x += 1
        force[0] += 1
    
    if r_y > santa_poses[nearest_idx][1]:
        r_y -= 1
        force[1] -= 1
    elif r_y < santa_poses[nearest_idx][1]:
        r_y += 1
        force[1] += 1

    return r_x, r_y, force, nearest_idx

def santa_move(idx):
    
    sx, sy = santa_poses[idx]

    min_dist = pow((r_x-sx), 2) + pow((r_y-sy), 2)

    m_x, m_y = 0, 0

    for dx, dy in s_offset:
        px, py = sx + dx, sy + dy

        dist = pow((r_x-px), 2) + pow((r_y-py), 2)
        if dist < min_dist:
            min_dist = dist
            m_x, m_y = dx, dy

    return sx+m_x, sy+m_y, [m_x, m_y]

def santa_interaction(idx2, move):
    
    sx, sy = santa_poses[idx2]
    sx += move[0]
    sy += move[1]

    if not 0 <= sx < size or not 0 <= sy < size:
        santa_status[idx2] = 2
    else:
        santa_poses[idx2] = [sx, sy]
        
        if [sx, sy] in santa_poses:
            santa_interaction(santa_poses.index([sx, sy]), move)

    return

r_x, r_y, move, idx = rudolph_move(r_x, r_y)

# λ£¨λŒν”„κ°€ μ‚°νƒ€ν•œν…Œ μΆ©λŒν•  λ•Œ
if [r_x, r_y] == santa_poses[idx]:
    sx, sy = santa_poses[idx]

    sx += r_force * move[0]
    sy += r_force * move[1]

    if not 0 <= sx < size or not 0 <= sy < size:
        santa_status[idx] = 2
    else:
        santa_status[idx] = 1
        santa_poses[idx] = [sx, sy]

        if [sx, sy] in santa_poses:
            santa_interaction(santa_poses.index([sx, sy]), move)

print(santa_poses)

# μ‚°νƒ€μ˜ μ›€μ§μž„
for idx in range(santa_alive):
    if santa_status[idx] == 2:
        continue
    elif santa_status[idx] == 1:
        santa_status[idx] = 0
    
    sx, sy, move = santa_move(idx)
    
    if [r_x, r_y] == santa_poses[idx]:
        sx -= s_force * move[0]
        sy -= s_force * move[1]

        if not 0 <= sx < size or not 0 <= sy < size:
            santa_status[idx] = 2
        else:
            santa_poses[idx] = [sx, sy]
            santa_status[idx] = 1

            if [sx, sy] in santa_poses:
                santa_interaction(santa_poses.index([sx, sy]), move)

print(santa_poses)
print(santa_status)
print(r_x, r_y)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants