www.acmicpc.net/problem/1697

 

1697번: 숨바꼭질

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 ��

www.acmicpc.net

 

문제해석

 

  • 수빈이가 동생을 잡으려고 하는데 2*X, X+1, X-1로 이동 가능함
  • 최소의 이동으로 동생의 위치에 도달하는 방법 찾기 (=최적의 길)-> BFS
  • 오직 BFS로만 풀리는 문제

 

SOL

  • BFS로 구현
#include <iostream>
#include <queue>

using namespace std;

int n, m, ans;
queue<pair<int, int>> q;
bool vi[1000001];

void solve() {
	q.push({ n, 0 });
	vi[n] = 1;
	while (!q.empty()) {
		int x = q.front().first;
		int y = q.front().second;
		q.pop();

		if (x == m) {
			ans = y;
			break;
		}

		for (int w = 0; w < 3; w++) {
			if (w == 0 && vi[x - 1] == 0 && x - 1 >= 0) {
				q.push({ x - 1, y + 1 });
				vi[x - 1] = 1;
			}
			else if (w == 1 && vi[x + 1] == 0 && x + 1 < 100001) {
				q.push({ x + 1, y + 1 });
				vi[x + 1] = 1;
			}
			else if (w == 2 && vi[x * 2] == 0 && x * 2 < 100001) {
				q.push({ x * 2, y + 1 });
				vi[x * 2] = 1;
			}
		}
	}
}

int main() {
	cin >> n >> m;
	solve();
	cout << ans << endl;
	return 0;
}

 

Java

import java.util.*;
import java.io.*;

class Location
{
	int x;
	int y;
	Location(int x, int y)
	{
		this.x = x;
		this.y = y;
	}
	}

public class Main
{
	static boolean[] vi = new boolean[100001];
		
	public static void bfs(int a, int b)
	{
		Arrays.fill(vi, false);
		Queue<Location> q = new LinkedList<Location>();
		
		q.add(new Location(a,0));
		vi[a] = true;
		
		while(!q.isEmpty())
		{
			Location temp = q.poll();
			
			if(temp.x == b)
			{
				System.out.print(temp.y);
				break;
			}
			
			int x = temp.x;
			int y = temp.y;
			
			x = temp.x-1;
			y = temp.y+1;
			
			if(x>=0 && vi[x] == false)
			{
				vi[x] = true;
				q.add(new Location(x,y));
			}
			
			
			x = temp.x+1;
			y = temp.y+1;
			
			if(x<=100000 && vi[x] == false)
			{
				vi[x] = true;
				q.add(new Location(x,y));
			}
			
			x = temp.x *2;
			y = temp.y+1;
			
			if(x<=100000 && vi[x] == false)
			{
				vi[x] = true;
				q.add(new Location(x,y));
			}
			
		}
		
	}
	
    public static void main(String[] args) throws IOException
    {
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	String str = br.readLine();
    	StringTokenizer st = new StringTokenizer(str);
    	int a = Integer.parseInt(st.nextToken());
    	int b  = Integer.parseInt(st.nextToken());
    	
    	bfs(a,b); 
    	
        
        
    }
}

programmers.co.kr/learn/courses/30/lessons/1845

 

코딩테스트 연습 - 폰켓몬

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다. �

programmers.co.kr

문제해설

  • nums에 폰켓몬 번호가 주어짐 (같은 번호는 같은 폰켓몬)
  • 고를 수 있는 폰켓몬은 nums의 갯수 / 2 
  • 최대한 result 가지의 폰켓몬을 고르는 방법 

sol

  • Set을 이용하여 구현 
  • 중복제거 한 Set의 갯수와 nums/2 의 갯수 중 더 큰 값이 답.

 

C++ 

#include <vector>
#include <set>
#include <iostream>
using namespace std;

int solution(vector<int> nums)
{
    int answer = 0;
    set<int> s;
    for(int i = 0 ; i < nums.size() ; i++)
    {
        s.insert(nums[i]);
    }
  
    int com = nums.size()/2;
    if(s.size() > com )
    {
        answer =com;
    }
    else
    {
        answer = s.size();
    }
    
    return answer;
}

Java 

  • Java는 C++의 set이 아닌 HashSet을 씀
import java.util.*;

public class 프로그래머스Lv2_폰켓몬_HashSet {

 
    static int solution(int[] nums) 
    {
        int answer = 0;
        HashSet<Integer> s = new HashSet<Integer>();
        //set<integer> s;
        for(int i = 0 ; i<nums.length ;i++)
        {
        	s.add(nums[i]);
        }
        int tempNum = nums.length /2;
        if(s.size() > tempNum )
        	answer = tempNum;
        else
        	answer = s.size();
        
        return answer;
   
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	 
		int nums1 []= {3,1,2,3}; 
		solution(nums1); 
	}
	
}

www.welcomekakao.com/learn/courses/30/lessons/42897

 

코딩테스트 연습 - 도둑질

도둑이 어느 마을을 털 계획을 하고 있습니다. 이 마을의 모든 집들은 아래 그림과 같이 동그랗게 배치되어 있습니다. 각 집들은 서로 인접한 집들과 방범장치가 연결되어 있기 때문에 인접한 ��

www.welcomekakao.com

문제설명

 

간단히 인접하지 않은 두 집을 털어 max 값을 구해주는 문제이다.

 

점화식

  • 첫번째 집부터 터는 경우 = 마지막 집 선택의 경우
  • 두번째 집부터 터는 경우 = 마지막 집 선택 X 경우 

현재 도둑질하려는 집의 돈 +  max ( (현재집 -2)집의 돈, (현재집 -1)집의 돈 )

 

C++

#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int dp[1000000] = { 0, };
int solution(vector<int> money)
{
	vector <long> one;
	vector <long> two;
	int msize = money.size();
	one.resize(msize, money[0]);
	two.resize(msize, money[1]);
	two[0] = 0;
	for (int i = 2; i <= msize - 2; i++)
		one[i] = max(one[i - 2] + money[i], one[i - 1]);

	for (int i = 2; i <= msize - 1; i++)
		two[i] = max(two[i - 2] + money[i], two[i - 1]);

	return max(one[msize - 2], two[msize - 1]);
}

int main()
{
	solution({ 1, 2, 3, 1, 2, 3 });
	return 0;
}

Java


import java.util.*;
public class 프로그래머스Lv4_도둑질_Dp {
	static int solution(int [] money)
	{
		//ArrayList<Integer> one;
		//ArrayList<Integer> two;
		int msize =money.length;
		int [] one  = new int [msize+1];
		int [] two  = new int [msize+1];
		
		one[0] = money[0];
		one[1] = money[0];
		one[2] = money[0];
		
		two[0] = money[1];
		two[1] = money[1];
		two[2] = money[1];
		
		//one.resize(msize, money[0]);
		//two.resize(msize, money[1]);
		//two[0] = 0;
		for (int i = 2; i <= msize - 2; i++)
			one[i] = Math.max(one[i - 2] + money[i], one[i - 1]);

		for (int i = 2; i <= msize - 1; i++)
			two[i] = Math.max(two[i - 2] + money[i], two[i - 1]);

		return Math.max(one[msize - 2], two[msize - 1]);
	}

	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		int [] num= {1,2,3,1,2,3};
		System.out.println(solution(num));
	}

}

'Algorithm' 카테고리의 다른 글

[백준 1697] 숨바꼭질 C++, Java  (0) 2020.09.03
[프로그래머스] 폰켓몬 C++, Java  (0) 2020.09.03
[프로그래머스] 단어변환  (0) 2020.07.20
[프로그래머스] 불량사용자  (0) 2020.07.20
[백준] 베스트앨범  (0) 2020.07.17

문자 검색/치환

  • Ctrl+F: 문자 검색
  • Ctrl+H:문자의 치환

직사각형 선택

Alt 키를 누른 상태에서 마우스로 원하는 직사각형 모양의 범위를 만든다.

자동 인덴트(indent)

  • Ctrl+K, Ctrl+D: 파일 전체의 인덴트 조정
  • Ctrl+K, Ctrl+F: 선택 범위의 인덴트 조정

코드 개요 확장/축소

  • Ctrl+M, Ctrl+L: 파일 전체의 개요 확장/축소
  • Ctrl+M, Ctrl+M: 선택 범위의 개요 확장/축소

주석

  • Ctrl+K, Ctrl+C: 선택 범위의 주석화
  • Ctrl+K, Ctrl+U: 선택 범위의 주석 해제

클립 보드 링

  • Ctrl+Shift+V: 클립 보드 링을 사용하여 이전에 복사한 데이터를 순환하면서 붙이기 할 수 있다.

함수 정의로 이동

  • F12: 선택한 함수의 정의로 이동

커서 위치 이력 기록

  • Ctrl + -(마이너스): 직전의 커서 위치로 돌아간다
  • Ctrl + Shift + -(마이너스): 다음 커서 위치로 나간다

 

 

https://jacking75.github.io/VS_tips01/

 

'C++' 카테고리의 다른 글

[C++] char 문자열 (기본, char[] 와 char* 의 차이점 등)  (0) 2020.09.24
[C++] 포인터(Pointer)  (0) 2020.07.23
[C++] 스택과 힙  (0) 2020.07.23
[C++] 메모리누수 체크  (0) 2020.07.23
[C++] char[] 와 char*의 차이  (0) 2020.07.22

 

1) 모든 .cpp, .h 창을 끈다.

 

2) 모두 접는다.

3) 다시 확장한다.  끝.

GetLine() 함수 

문제점 1) 가나다 라마바 사아자 라고 입력이 되었다고 치면 cin 또는 scanf로 입력 받을 시 가나다에서 끊기고 만다.

해결 : getline 함수를 이용

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

int main()
{
 
	char name[20];
	char dessert[20];
	
	cout << "name" << endl;
	cin.getline(name, 20);  //20글자 까지 받을 수 있다.
	cout << "dessert" << endl;
	cin.getline(dessert, 20);

	cout << "good" << dessert;
	cout << "dessert " << name << "sir " << endl;

	return 0;
}

 

문제점 2) 위의 코드로 입력 받을 시 한글이 무조건 깨진다.

이유 : ASCIII (거의 100%이거 때문임) ->

해결 : 멀티바이트 문자 집합 이용 (거의 100% 이게 해결법임)

단, 해당 문자 집합을 이용하면 그에 맞는 함수도 가져가야한다.

한글을 출력하기 위해서는 로케일 설정을 한국으로 바꿔줘여한다.

 

전체 로케일 설정

  • locale::global(locale("kor"));

부분 로케일 설정

  • wcout.imbue(locale("kor"));

코드

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

int main()
{
	wcout.imbue(locale("kor"));//한국으로 지역설정
	wcin.imbue(locale("kor")); 
	wchar_t name[20];
	wchar_t dessert[20];
	
	wstring str1;
	wstring str2; 

	wcout << "name" << endl;
	wcin.getline(name, 20);
	wcout << "dessert" << endl;
	wcin.getline(dessert, 20);

 
	wcout << "good" << dessert;
	wcout << "dessert " << name << "sir " << endl;


	return 0;
}

 

만약 wchar_t가 아닌 string에 담고 싶다면 string 대신 wstring을 사용한다.

코드 

	wcout.imbue(locale("kor"));//한국으로 지역설정
	wcin.imbue(locale("kor"));
    
	wstring str1;
	getline(wcin, str1);

 

 

 

'Algorithm > Algorithm_Tip' 카테고리의 다른 글

[Java 입출력] StringTokenizer  (0) 2020.09.08
[JAVA 입력 TIP]  (0) 2020.09.08
[탐색] 이분탐색 lower_bound, upper_bound  (0) 2020.07.21
순열&조합  (0) 2020.07.13
입력 팁  (0) 2020.06.28

마인드풀니스(Mindfullness) : 완벽한 휴식법

집중력 저하는 잡념에서 비롯됩니다.

 

이 쓸데없는 잡념을 없애는 데 큰 도움을 주는 마인드풀니스의 핵심은 '이것'이다.

 

'지금, 여기에 집중하는 것' 무의식중으로 하던 내 행동을 스스로 인지 하는 것

 

뇌의 모든 피로와 스트레스는 지난 일에 연연하고 앞으로 일어날 일에 불안해 하는 것에서 시작 된다.

 

그럴 때일수록 '지금 여기에 있는 나' 에게 더욱 집중해야 한다.

 

마인드풀니스의 방법 첫번째 '호흡에 집중하기' 호흡에 집중하다가 얼마 지나지 않아 다른 생각(잡념)이 떠오르면 그때는

 

'지금 생각이 떠오르는구나' 생각하고 다시 호흡에 집중한다.  따라서 '지금'에만 집중한다.

 

기본자세

1> 바른자세로 다리 꼬지 않고 발바닥을 대고 눈을 감는다.

2> 몸의 감각을 의식한다. 발바닥, 마루, 엉덩이와 의자, 중력의 감각을 느껴본다.

3> 호흡을 의식한다. 호흡의 깊이 들숨 날숨의 온도차이 등 호흡에 관계하는 감각에 의식

4> 잡년이 떠오를 때 잡념이 생기는게 당연하므로 자책말고 다시 호흡에 집중한다.

 

즉, 미래나 과거를 너무 생각하지말고 현실에 온전히 집중하여 사는것. 다가올 출근과 월요일을 생각하지말고 지금현재

 

의 일요일을 사는것.

포인터(Pointer)

  • 프로그램이 변수를 인스턴스화 할때 사용 가능한 메모리 주소가 변수에 자동으로 할당되고, 변수에 할당된 값은 이 메모리 주소에 저장된다.
int x;
  • CPU가 위 문장을 실행하면 RAM의 메모리 조각이 따로 설정됨.
예를 들어 변수 x에 메모리 위치 140이 할당 되었다고 가정하면, 프로그램에서 변수 x를 표현식 또는 명령문으로 접근할 때마다 값을 얻으려면 메모리 위치 140을 찾아야함.
변수의 좋은 점은 우리가 어떤 특정한 메모리 주소가 할당되는지 걱정할 필요가 없다는 것이다.
지정된 변수를 참조하면 컴파일러에서 이 이름이 할당된 메모리 주소로 반환한다.

주소 연산자(&) (The address-of operator(&))

주소 연산자 &를 사용하면 변수에 할당된 메모리 주소를 확인할 수있다.

#include <iostream>

int main()
{
	int x=5;
	cout<<x<<endl;
	cout<<&x<<endl;
    
    return 0;
}

역참조 연산자(*) (The dereference operator(*))

  • 변수의 주소를 얻는 것 자체로는 그다지 유용하지 않다.
  • 역참조 연산자(*)를 사용하면 특정 주소에서 값에 접근할 수있다.
 int main() 
{
	int x = 5; 
	std::cout << x << '\n'; // print the value of variable x 
	std::cout << &x << '\n'; // print the memory address of variable x 
	std::cout << *&x << '\n'; /// print the value at the memory address of variable x 
	return 0; 
} 

// prints: 
// 5 
// 0027FEA0 
// 5

역참조 연산자(*)는 곱셈 연사자처럼 보이지만, 역참조 연산자는 단항이고 곱셈 연산자는 이항 연산자이다.

 

포인터(Pointer)

  • 포인터는 어떠한 값을 저장하는게 아닌 메모리 주소를 저장하는 변수이다.
  • C++에서 가장 혼란스러운 부분이라고 생각X -> 매우간단하다. 

포인터 선언

 포인터 변수는 일반 변수처럼 선언되며, 자료형과 변수 이름사이에 별포(*)가 붙는다.

  • 자료형* 포인터 이름;
int* iPtr; // int형 포인터 
double* dPtr; // double형 포인터 
int* iPtr2, *iPtr3; // int형 두 개의 포인터 선언
  • 여러 포인터 변수를 선언하는 경우 별표가 각 변수에 포함되어야한다. 초기화 하지않으면 쓰레기 값

포인터에 값 할당(Assingning a value to a pointer)

  • 포인터는 메모리 주소만 저장하므로, 포인터에 값을 할당할 때 그 값은 주소여야한다.
  • 포인터로 하는 가장 흔한 작업은 다른 변수의 주소를 저장하는 것이다.
int value = 5; 
int *ptr = &value; // 변수값의 주소로 ptr 초기화
 

double *dPtr = 0x0012FF7C; // not okay (정수 리터럴을 할당하는 것으로 취급된다.)

the address-of operator returns a pointer

  • 주소 연산자 &는 피연산자의 주소를 리터럴로 반환하지 않는다.
  • 대신 피연사자의 주소가 들어있는 포인터를 반환하다.

 

Dereferencing pointers 

  • 어떤 것을 가리키는 포인터변수가 있다면, 역참조 변환자(*) 를 통해 포인터가 가리키는 주소의 값을 알 수 있다.
int value = 5; 
std::cout << &value; // value의 주소를 출력한다. 
std::cout << value; // value의 값을 출력한다. 

int *ptr = &value; // ptr은 value를 가리킨다. 
std::cout << ptr; // ptr이 가리키는 주소를 출력한다. (=&value) 
std::cout << *ptr; // ptr을 역참조한다. (ptr이 가리키는 주소의 값을 출력한다. =value) 

// 0012FF7C 
// 5 
// 0012FF7C 
// 5
  • 이러한 이유(주소의 값을 알아내는 것) 때문에 반드시 자료형을 가져야한다. 자료형이 없으면 역참조 시 가리키는 내용을 해석하는 방법을 알지 못함.
  • *ptr은 변수이므로 다른 변수를 할당 가능하다.
int value =5;
int *ptr= &value;

*ptr= 7; //가능

 

요약(Summary)

  • 포인터는 메모리 주소를 저장하는 변수이다.
  • *를 사용하여 저장한 메모리의 주소의 값을 알 수있다.
  • 가비지 포인터를 역참조하면 응용 프로그램이 종료될 수있다.

+ Recent posts