반응형

https://www.acmicpc.net/problem/19238

 

19238번: 스타트 택시

첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다

www.acmicpc.net

1.문제설명

택시가 손님을 정해진 위치에 데려다 주면서 이동한 거리를 바탕으로 연료의 양을 조건에 따라 계산해야하는 문제이다.

 

이 문제를 풀기 위해 BFS가 여러번 쓰인다.

 

 

1. 첫번째로 택시가 모든 손님과 모든 손님의 도착점으로 이동할 수 있는지 검사해야한다.

벽으로 경로가 끊어져 있을 수 있기 때문에 Flood Fill 방식으로 계산한다.

 

2. 두번째로 가까이 있는 손님을 구하기 위해 Flood Fill 방식으로 다시

현재 택시의 위치와 손님과의 거리를 구한다.

이때 주의해야할 점은 손님을 발견하자마자 BFS를 종료하면 안되고,

손님을 발견하더라도 전체 맵을 다 돌 때까지 BFS를 실행해야한다.

 

map의 크기가 작기 때문에 시간초과에 걸리지 않는다.

이렇게 해야하는 이유는 먼저 모든 손님에 대하여 각 손님까지의 거리를 구한 후

거리가 동일한 경우 행과 열의 숫자를 보고 손님을 정해야하기 때문이다.

만약 BFS를 돌다 손님 하나를 발견하자마자 종료한다면

같은 거리에 위치했지만 행과 열 정보에서 우선순위를 지니는 손님을 탐색하지 못한다.

 

 

3. 세번째는 손님 ---- 도착점 사이의 거리를 구하기 위해 BFS를 사용한다.

Map의 중간 중간 벽이 존재하기 때문에 BFS나 DFS로 거리를 구해야 한다.

 

이러한 세가지 기능을 구현해주면 문제를 해결할 수 있다.

 


2.문제풀이코드 C++

#include <bits/stdc++.h>

using namespace std;
int N, M, F; //F : 초기연료
bool arr[21][21]; //벽
int stx, sty; //driver 시작점
int guestInfo[403][4]; // guest마다 시작x,y 종점x,y
bool checkGuestEnd[403];

int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

void Input();

bool gameCheck(int _stx, int _sty) { //flood Fill -> driver로부터 guest 시작점,종점 경로가 연결 되어 있는지확인
    bool ch[21][21] = {0};
    queue<pair<int, int> > Q;

    ch[_stx][_sty] = 1;
    Q.push({_stx, _sty});

    while (!Q.empty()) {
        auto cur = Q.front();
        Q.pop();

        for (int i = 0; i < 4; i++) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];

            if (nx <= 0 || nx > N || ny <= 0 || ny > N) continue;
            if (ch[nx][ny] || arr[nx][ny]) continue;
            Q.push({nx, ny});
            ch[nx][ny] = 1;
        }
    }

    for (int i = 1; i <= M; i++) {
        int x = guestInfo[i][0];
        int y = guestInfo[i][1];
        int nx = guestInfo[i][2];
        int ny = guestInfo[i][3];

        if (ch[x][y] == 0 || ch[nx][ny] == 0) {
            return false;
        }
    }
    return true;
}

pair<int,int> chooseGuest(int _stx, int _sty){
    int ch[21][21] = {0};
    queue<pair<int, int> > Q;

    ch[_stx][_sty] = 1;
    Q.push({_stx, _sty});

    while (!Q.empty()) {
        auto cur = Q.front();
        Q.pop();

        for (int i = 0; i < 4; i++) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];

            if (nx <= 0 || nx > N || ny <= 0 || ny > N) continue;
            if (ch[nx][ny] > 0 || arr[nx][ny]) continue;
            Q.push({nx, ny});
            ch[nx][ny] = ch[cur.first][cur.second] + 1;

        }
    }

    int minDist = 100000;
    int nextGuest = -1;

    for(int i=1; i<=M; i++){
        if(checkGuestEnd[i]) continue;

        int curDist = ch[guestInfo[i][0]][guestInfo[i][1]];
        if( curDist< minDist){
            nextGuest = i;
            minDist = curDist;
        }
        else if(curDist == minDist){
            if(guestInfo[nextGuest][0] > guestInfo[i][0]){
                nextGuest = i;
            }
            else if(guestInfo[nextGuest][0] == guestInfo[i][0]){
                if(guestInfo[nextGuest][1] > guestInfo[i][1]){
                    nextGuest = i;
                }
            }
        }
    }

    return {nextGuest, minDist-1};
}

int calDistance(int _stx, int _sty, int enx, int eny){
    int ch[21][21] = {0};
    queue<pair<int, int> > Q;

    ch[_stx][_sty] = 1;
    Q.push({_stx, _sty});

    while (!Q.empty()) {
        auto cur = Q.front();
        Q.pop();

        for (int i = 0; i < 4; i++) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];

            if (nx <= 0 || nx > N || ny <= 0 || ny > N) continue;
            if (ch[nx][ny] > 0 || arr[nx][ny]) continue;
            Q.push({nx, ny});
            ch[nx][ny] = ch[cur.first][cur.second] + 1;
            if(nx==enx && ny==eny) break;
        }
    }

    return ch[enx][eny]- 1;
}

bool allGuestGoHome(){
    for(int i=1; i<=M; i++){
        if(!checkGuestEnd[i]) return false;
    }
    return true;
}


int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    Input();


    //벽 때문에 깃발이나 손님한테 갈 수 없는 경우
    if (!gameCheck(stx,sty)) {
        cout << -1 << '\n';
        return 0;
    }


    while(!allGuestGoHome()) {
        auto nextGuest = chooseGuest(stx, sty);
        int guest = nextGuest.first;
        int toGuestDist = nextGuest.second;
        int toFlagDist = calDistance(guestInfo[guest][0], guestInfo[guest][1], guestInfo[guest][2], guestInfo[guest][3]);


        if(F<toGuestDist + toFlagDist){
            cout << -1 << '\n';
            return 0;
        }
        else{
            //guest 집에감, 연료 동기화
            checkGuestEnd[guest] = 1;
            F = F - toGuestDist + toFlagDist;

            //driver 이동
            stx = guestInfo[guest][2];
            sty = guestInfo[guest][3];
        }
    }

    cout << F << '\n';
}


void Input() {
    cin >> N >> M >> F;

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> arr[i][j];
        }
    }
    //driver start
    cin >> stx >> sty;

    for (int i = 1; i <= M; i++) {
        cin >> guestInfo[i][0] >> guestInfo[i][1] >> guestInfo[i][2] >> guestInfo[i][3]; //start x,y / end x, y
    }


}
반응형
반응형

React 설치

반응형

'Web > React' 카테고리의 다른 글

react-beautiful-dnd  (0) 2022.07.22
[React] setState는 비동기로 동작한다  (0) 2022.07.16
반응형
import React, { useState, useTransition } from 'react'
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';

export default function List({ todoData, setTodoData }) {
    const handleCompleteChange = (e, id) => {
        e.stopPropagation();
        let newTodo = todoData.map((todo) => {
            if (todo.id === id) {
                todo.completed = !todo.completed;
            }
            return todo;
        })

        setTodoData(newTodo);
    }


    const handleClick = (id) => {
        let newTodo = todoData.filter(todo => todo.id !== id);
        setTodoData(newTodo);
    }

    const handleEnd = (result) => {
        console.log("result", result);

        if (!result.destination) return;

        const newTodoData = todoData;
        const [reorderItem] = newTodoData.splice(result.source.index, 1);
        newTodoData.splice(result.destination.index, 0, reorderItem);
        setTodoData(newTodoData);
    }

    return (
        <div>
            <DragDropContext onDragEnd={handleEnd}>
                <Droppable droppableId='todo'>
                    {(provided) => (
                        <div {...provided.droppableProps} ref={provided.innerRef}>
                            {todoData.map((data, index) => {
                                return (
                                    <Draggable
                                        key={data.id}
                                        draggableId={data.id.toString()}
                                        index={index}
                                    >
                                        {(provided, snapshot) => (
                                            <div key={data.id} {...provided.draggableProps}
                                                ref={provided.innerRef}
                                                {...provided.dragHandleProps}>
                                                <div className={`${snapshot.isDragging ? "bg-gray-400 " : "bg-gray-100 "} flex items-center justify-between w-full px-4 py-1 my-2 text-gray-600 border rounded`}>
                                                    <div>
                                                        <input type="checkbox" defaultChecked={false} onClick={(e) => handleCompleteChange(e, data.id)}></input>
                                                        <span className={data.completed ? 'line-through' : undefined}>{data.title}</span>
                                                    </div>
                                                    <div>
                                                        < button className='px-4 py-2 float-right' onClick={() => { handleClick(data.id) }} > x</button>
                                                    </div>
                                                </div>
                                            </div>
                                        )}
                                    </Draggable>
                                )
                            })
                            }
                            {provided.placeholder}
                        </div>
                    )}
                </Droppable>
            </DragDropContext>
        </div>
    )
}
반응형

'Web > React' 카테고리의 다른 글

npx create-react-app ./  (0) 2022.07.23
[React] setState는 비동기로 동작한다  (0) 2022.07.16
반응형

https://www.acmicpc.net/problem/19237

 

19237번: 어른 상어

첫 줄에는 N, M, k가 주어진다. (2 ≤ N ≤ 20, 2 ≤ M ≤ N2, 1 ≤ k ≤ 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미

www.acmicpc.net

1.문제설명

구현해야할 부분 단위가 많은 시뮬레이션 문제이다.

 

각 부분에 대하여 기능을 잘 분리하고

올바른 순서로 기능을 수행해야 문제를 해결 할 수 있다.

 

주의해야할 점은

모든 상어가 동시에 움직이고 동시에 냄새를 뿌린다는 점이다.

 

즉 상어가 움직이면서 냄새를 뿌리도록 구현하면

잘못된 구현이다.

 

 

 

크게 구현해야할 것은

1. 턴 마다 상어 움직이기

2. 냄새 뿌리기

3. 1번 상어만 남아있는지 확인하기

 

1번을 구현하기 위해서 부분 문제로

각 상어마다 방향정보를 바탕으로

이동해야할 위치와 방향을 구해야한다.

 

이 때 모든 상어는 동시에 움직인다는 조건을 지니므로

상어의 위치를 각 상어마다 옮기고 바로 적용해주는 것이 아니라

현재 위치와 다음 턴의 위치를 구분 짓기 위해서

다른 배열을 하나 두어서 체크를 해주는 것도 중요한 포인트다.

 

 


 

2.문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int N, M, K;
int sharkState[500][3];
int dirPriority[500][5][5];
//20X20 (smell, shark)
int smell[30][30][2];

int dx[5] = {0, -1, 1, 0, 0};
int dy[5] = {0, 0, 0, -1, 1};


void Input();


void sharkNextState(int sharkNum, int &x, int &y, int &d) {
    int curX = x;
    int curY = y;
    int curD = d;

    //먼저 현재 방향으로 이동 가능한지 체크
    int nx = -1;
    int ny = -1;
    int nd = -1;

    for (int i = 1; i <= 4; i++) {
        nd = dirPriority[sharkNum][curD][i];
        nx = curX + dx[nd];
        ny = curY + dy[nd];

        if (nx <= 0 || nx > N || ny <= 0 || ny > N) continue;
        if (smell[nx][ny][0] > 0) continue;
        x = nx;
        y = ny;
        d = nd;
        return ;
    }

    //네 방향모두 냄새로 가득 차있으니 자신의 냄새있는 칸 찾기
    for (int i = 1; i <= 4; i++) {
        nd = dirPriority[sharkNum][curD][i];
        nx = curX + dx[nd];
        ny = curY + dy[nd];

        if (nx <= 0 || nx > N || ny <= 0 || ny > N) continue;
        if (smell[nx][ny][1] != sharkNum) continue;
        x = nx;
        y = ny;
        d = nd;
        return;
    }
}


void allSharkCheck() {
    bool nextMap[30][30] = {0};
    for (int i = 1; i <= M; i++) {
        int curX = sharkState[i][0];
        int curY = sharkState[i][1];
        int curD = sharkState[i][2];

        //죽은 상어 제외
        if (curX < 0) continue;
        sharkNextState(i, curX, curY, curD);

        //번호 작은 상어 이미 존재
        if (nextMap[curX][curY]) {
            sharkState[i][0] = -1;
            continue;
        }

        sharkState[i][0] = curX;
        sharkState[i][1] = curY;
        sharkState[i][2] = curD;
        nextMap[curX][curY] = 1;
    }
}


bool gameEndCheck() {
    //1번 상어 살아 있고
    if (sharkState[1][0] < 0) return false;
    //다른 상어 모두 죽었을 때
    for (int i = 2; i <= M; i++) {
        if (sharkState[i][0] > 0) {
            return false;
        }
    }
    return true;
}

void spreadSmell(){
    for (int i = 1; i <= M; i++) {
        int curX = sharkState[i][0];
        int curY = sharkState[i][1];
        if (curX < 0) continue;
        smell[curX][curY][0] = K;
        smell[curX][curY][1] = i;
    }
}


void decrementSmell(){
    for(int i=1; i<=N;i++){
        for(int j=1; j<=N; j++){
            if(smell[i][j][0]>0){
                smell[i][j][0]--;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    Input();
    for (int i = 1; i <= 1000; i++) {
        spreadSmell();
        allSharkCheck();
        if (gameEndCheck()) {
            cout << i << '\n';
            return 0;
        }
        decrementSmell();
    }
    cout << -1 << '\n';
}


void Input() {
    cin >> N >> M >> K;
    //x, y
    for (int x = 1; x <= N; x++) {
        for (int y = 1; y <= N; y++) {
            int sk;
            cin >> sk;

            if (sk > 0) {
                sharkState[sk][0] = x;
                sharkState[sk][1] = y;
            }
        }
    }
    //dir
    for (int i = 1; i <= M; i++) {
        cin >> sharkState[i][2];
    }

    for (int i = 1; i <= M; i++) {
        for (int j = 1; j <= 4; j++) {
            for (int k = 1; k <= 4; k++) {
                cin >> dirPriority[i][j][k];
            }
        }
    }
}
반응형
반응형

https://www.acmicpc.net/problem/19236

 

19236번: 청소년 상어

첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는

www.acmicpc.net

#include <bits/stdc++.h>

using namespace std;


int dx[9] = {0, -1, -1, 0, 1, 1, 1, 0, -1};
int dy[9] = {0, 0, -1, -1, -1, 0, 1, 1, 1};

int ans = 0;

void moveFish(int _curFishPosition[][4], int _curFishes[][3], int _skx, int _sky) {
    for (int i = 1; i <= 16; i++) {
        int x = _curFishes[i][0];
        int y = _curFishes[i][1];
        int d = _curFishes[i][2];


        if (x < 0) continue;

        int nx = x;
        int ny = y;
        int nd = d;
        for (int j = 0; j < 8; j++) {
            nx = x + dx[nd];
            ny = y + dy[nd];
            nd++;
            if (nd >= 9) nd = 1;

            if (nx < 0 || nx >= 4 || ny < 0 || ny >= 4) continue;
            if (nx == _skx && ny == _sky) continue;

            break;
        }

        nd--;
        if (nd == 0) nd = 8;


        _curFishes[i][0] = nx;
        _curFishes[i][1] = ny;
        _curFishes[i][2] = nd;


        if(_curFishPosition[nx][ny]<=0){
            cout << "Erorr!!" << '\n';
            cout <<_curFishPosition[nx][ny] << ' ' << nx << ' ' << ny << '\n';
        }

        int changeFish = _curFishPosition[nx][ny];
        //살은 경우만 x,y 동기화해줌
        if(_curFishes[changeFish][0] >= 0) {
            _curFishes[changeFish][0] = x;
            _curFishes[changeFish][1] = y;
        }

        swap(_curFishPosition[nx][ny], _curFishPosition[x][y]);

    }
}


void backTrack(int L, int _skx, int _sky, int _skd, int _fishPosition[][4], int _fishes[][3], int sum) {
    ans = max(ans, sum);
    int curFishes[17][3];
    int curFishPosition[4][4];
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            curFishPosition[i][j] = _fishPosition[i][j];
        }
    }
    for (int i = 0; i < 17; i++) {
        for (int j = 0; j < 3; j++) {
            curFishes[i][j] = _fishes[i][j];
        }
    }

    //물고기 이동
    moveFish(curFishPosition, curFishes, _skx, _sky);



    //상어 이동
    int n_skx = _skx;
    int n_sky = _sky;
    int n_skd = _skd;

    for (int i = 0; i < 4; i++) {
        n_skx += dx[_skd];
        n_sky += dy[_skd];


        if (n_skx < 0 || n_skx >= 4 || n_sky < 0 || n_sky >= 4) continue;
        int curFish = curFishPosition[n_skx][n_sky];
        int curFishX = curFishes[curFish][0];

        //물고기 없는 칸 인경우 x==-1
        if (curFishX < 0) continue;
        n_skd = curFishes[curFish][2];

        curFishes[curFish][0] = -1;
        backTrack(L + 1, n_skx, n_sky, n_skd, curFishPosition, curFishes, sum + curFish);
        curFishes[curFish][0] = curFishX;
    }
}


int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int fishPosition[4][4];

//16fishes x, y, dir;
    int fishes[17][3];


    for (int x = 0; x < 4; x++) {
        for (int y = 0; y < 4; y++) {
            int a, b;
            cin >> a >> b;

            fishPosition[x][y] = a;
            fishes[a][0] = x;
            fishes[a][1] = y;
            fishes[a][2] = b;
        }
    }

    int skx = 0;
    int sky = 0;

    //잡아먹으면 0으로 표시
    ans += fishPosition[skx][sky];
    int skd = fishes[fishPosition[skx][sky]][2];
    fishes[fishPosition[skx][sky]][0] = -1;
    backTrack(0, skx, sky, skd, fishPosition, fishes, ans);

    cout << ans << '\n';
}
반응형
반응형

app.js

var mongoose = require('mongoose');

const { Post } = require("./models")

mongoose.connect("mongodb://localhost:27017/myapp")

mongoose.connection.on("connected", () => {
    console.log("연결 완료");
})

mongoose.connection.on("disconnected", () => {
    console.log("연결 끊김");
})


async function main() {
    await Post.create({
        title: "제목3",
        content: "내용3",
        etc: "etc",
    })
}

main();


async function findList() {
    return await Post.find({})
}

findList().then((res) => {
    console.log(res.map((item) => { return item.title === '제목' }));
})

async function findItem() {
    return await Post.find({ title: "제목2" });
}

findItem().then((res) => {
    console.log(res);
})


async function changeitem() {
    res = await Post.findOneAndUpdate({
        id: '62d4e1b3d6408bbd8909a939',
        title: '12345'
    });

    console.log(res);
}

changeitem();



(async function deleteFun() {
    res = await Post.deleteOne({
        id: "62d4e1e2382904f6f3402a68",
    })
    console.log(res);
})()

 

models/schemas/board.js

const { Schema } = require("mongoose")

const PostSchema = new Schema({
    title: String,
    content: String,
    etc: String,
},
    {
        timestamps: true
    });

module.exports = PostSchema;

 

models/index.js

const mongoose = require("mongoose")
const PostSchema = require("./schemas/board")

exports.Post = mongoose.model("Post", PostSchema);
반응형
반응형
event.stopPropagation();
반응형

'Web > javascript' 카테고리의 다른 글

appendChild를 이용하여 drag Event 만들기  (0) 2022.08.10
자바스크립트 객체 선언, 상속  (0) 2022.01.27
반응형
  handleReset(event) {
    this.setState(() => {
      return { searchKeyword: "" }
    }, () => {
      console.log("TODO: handleReset", this.state.searchKeyword);
    })
  }

 

반응형

'Web > React' 카테고리의 다른 글

npx create-react-app ./  (0) 2022.07.23
react-beautiful-dnd  (0) 2022.07.22

+ Recent posts