www.acmicpc.net/problem/14716

 

14716번: 현수막

혁진이의 생각대로 프로그램을 구현했을 때, 현수막에서 글자의 개수가 몇 개인지 출력하여라.

www.acmicpc.net

그냥 전형적인 dfs/bfs문제였다. 섬 갯수 세는 문제와 매우 유사했다.

 

단, 4방향이 아닌 8방향을 고려하는 것만 조심하면 쉬운 문제였다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

queue<pair<int, int>> q;
int map[1000][250];
int ans, m, n;
int dx[8] = { -1,-1,-1,0,0,1,1,1 };
int dy[8] = { -1,0,1,-1,1,-1,0,1 };

void bfs(int x, int y) {
	q.push({ x, y });
	map[x][y] = 0;
	while (!q.empty()) {
		int a = q.front().first;
		int b = q.front().second;
		q.pop();
		for (int i = 0; i < 8; i++) {
			if (a + dx[i] >= 0 && a + dx[i] < m && b + dy[i] >= 0 && b + dy[i] < n
				&& map[a + dx[i]][b + dy[i]] == 1) {
				map[a + dx[i]][b + dy[i]] = 0;
				q.push({ a + dx[i], b + dy[i] });
			}
		}
	}
	ans++;
	return;
}

int main() {
	cin >> m >> n;
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			cin >> map[i][j];
		}
	}
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (map[i][j] == 1) {
				bfs(i, j);
			}
		}
	}
	cout << ans;
	return 0;
}

www.acmicpc.net/problem/13549

 

13549번: 숨바꼭질 3

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

www.acmicpc.net

그냥 단순한 bfs 문제인줄 알았지만 간선이 0인 경우를 고려해야 해서 까다로운 문제였다..

 

결국 해결 하지 못해 힌트를 보고 말아서 좀 아쉬운 문제였다..

 

참고: www.acmicpc.net/board/view/38887#comment-69010

 

글 읽기 - [13549-숨바꼭질3] BFS 큐에 넣는 순서 질문

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

위에서 나오듯이 

1. 다익스트라 알고리즘을 사용하는 법

 

2. 0-1 BFS: 간선이 0(순간이동)을 넣을 떄 큐의 맨 앞에 넣는 법

 

3. * 2를 별도의 간선으로 생각하지 않고, +1이나 -1에 의한 좌표를 큐에 넣을 때 그 좌표의 2의 거듭제곱 배인 좌표들을 전부 큐에 넣는 방법

 

위의 세가지 방법 중에 하나를 사용하는 되는 문제였고 난 덱을 사용해서 결국 2번 방법을 사용해 풀 수 있었다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;

deque<pair<int, int>> dq;
int visit[100001];
int n, k;

void bfs(int x) {
	visit[x] = 1;
	dq.push_back({ x, 0 });
	while (!dq.empty()) {
		int y = dq.front().first;
		int z = dq.front().second;
		dq.pop_front();
		if (y == k) {
			cout << z;
			return;
		}
		if (2 * y <= 100000 && visit[2 * y] == 0) {
			visit[2 * y] = 1;
			dq.push_front({ 2 * y , z});
		}
		if (y - 1 >= 0 && visit[y - 1] == 0) {
			visit[y - 1] = 1;
			dq.push_back({ y - 1, z+1 });
		}
		if (y + 1 <= 100000 && visit[y + 1] == 0) {
			visit[y + 1] = 1;
			dq.push_back({ y + 1, z+1 });
		}
	}
}

int main() {
	cin >> n >> k;
	bfs(n);
	return 0;
}

www.acmicpc.net/problem/1707

 

1707번: 이분 그래프

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수

www.acmicpc.net

처음엔 그냥 두 개의 벡터를 만들어서 나누는 식으로 구현을 하려 했지만 실패했고 결국 답을 볼 수 밖에 없었다.

 

1. 큐와 간선 그래프 등을 포함해 모든 것을 테스트 케이스마다 초기화 해주기

 

2. 연결 그래프가 아닐 수도 있다는 것

 

이 두가지가 중요한 문제였다고 생각한다.

 

결국 푼 방법은 0, 1, 2 세가지의 종류로 정점들을 나눴고 이를 활용해서 풀 수 있었다.

참고: hugssy.tistory.com/231

 

백준 1707번: 이분 그래프 (C++)

https://www.acmicpc.net/problem/1707 가령 1--2--3--4 이러한 연결 관계를 가지는 그래프가 주어지면, 1을 빨간색, 2를 초록색으로 칠하고, 다시 3을 빨간색 4를 초록색 이렇게 두 가지의 색을 이용하여, 그래

hugssy.tistory.com

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;

bool c = true;
int k, v, e;
queue<int> q;
vector<int> edges[20001];
int visit[20001];

void bfs(int x) {
	q.push(x);
	visit[x] = 1;
	while (!q.empty()) {
		int y = q.front();
		q.pop();
		for (int i = 0; i < edges[y].size(); i++) {
			int z = edges[y][i];
			if (visit[z] != 0 && visit[y] == visit[z]) {
				c = false;
				return;
			}
			if (visit[z] > 0) {
				continue;
			}
			q.push(z);
			visit[z] = visit[y] % 2 + 1;
		}
	}
}

int main() {
	int a, b;
	cin >> k;
	while (k--) {
		cin >> v >> e;
		for (int i = 0; i < e; i++) {
			cin >> a >> b;
			edges[a].push_back(b);
			edges[b].push_back(a);
		}
		for (int i = 1; i <= v; i++) {
			if (visit[i] == 0) {
				bfs(i);
			}
			if (!c) {
				cout << "NO" << "\n";
				break;
			}
		}
		if (c) {
			cout << "YES" << "\n";
		}
		while (!q.empty()) {
			q.pop();
		}
		for (int i = 1; i <= v; i++) {
			visit[i] = 0;
			edges[i].clear();
		}
		c = true;
	}
	return 0;
}

www.acmicpc.net/problem/1967

 

1967번: 트리의 지름

파일의 첫 번째 줄은 노드의 개수 n(1 ≤ n ≤ 10,000)이다. 둘째 줄부터 n-1개의 줄에 각 간선에 대한 정보가 들어온다. 간선에 대한 정보는 세 개의 정수로 이루어져 있다. 첫 번째 정수는 간선이 연

www.acmicpc.net

하루 넘게 고민해서 겨우 푼 문제이다..

 

처음엔 단순히 2개의 간선을 가지는 노드들을 dfs 두번 보내서 각각의 간선 가중치의 합을 더하고 그 중 최댓값을 출력하게 풀려했는데 잘 안되었다.

 

반례를 보고 깨달았는데 이진 트리가 아니라서 간선이 한 방향에만 있는 경우, 여러개 있는 경우를 고려해주어야 했던 것이다.

 

그래서 런타임 에러 등을 통해 고생하다가 결국 풀 수 있었다.

 

1. 간선의 내용을 모두 받아오고 2개 이상의 간선을 가지는 노드를 따로 빼준다. (1은 초기 상태로 무조건 넣어줌)

 

2. 그렇게 구한 노드들을 모두 확인하는데, 각 노드의 아래에 있는 간선들의 합을 더해주되, 최댓값과 그 두번째 값을 저장하여 정답 벡터에 넣어준다.

 

3. 정답 벡터에 들어가 있는 값들 중 최댓값 출력

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector <pair<int, int>> v[10001];
vector<int> v2;
vector<int> ans;
int cnt[10001];
int x, n;

void dfs(int b, int c) {
	if (v[b].empty()) {
		x = max(x, c);
		return;
	}
	for (int j = 0; j < v[b].size(); j++) {
		c += v[b][j].second;
		dfs(v[b][j].first, c);
		c -= v[b][j].second;
	}

}

int main() {
	int a, b, c;
	cin >> n;
	if (n == 1) {
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n-1; i++) {
		cin >> a >> b >> c;
		v[a].push_back({ b,c });
		cnt[a]++;
	}
	v2.push_back(1);
	for (int i = 2; i <= n; i++) {
		if (cnt[i] > 1) {
			v2.push_back(i);
		}
	}
	for (int i = 0; i < v2.size(); i++) {
		int res = 0;
		int m1 = 0, m2 = 0;
		for (int j = 0; j < v[v2[i]].size(); j++) {
			dfs(v[v2[i]][j].first, v[v2[i]][j].second);
			m2 = max(m2, min(m1,x));
			m1 = max(m1, x);
			x = 0;
		}
		ans.push_back(m1+m2);
	}
	cout << *max_element(ans.begin(), ans.end());
	return 0;
}

www.acmicpc.net/problem/1759

 

1759번: 암호 만들기

첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다.

www.acmicpc.net

처음엔 그냥 next_permutation을 사용하고 l개 만큼 만 출력하는 식으로 해결하려 했지만 메모리 초과가 나서 시간이 꽤 걸렸던 문제이다.

 

메모리 초과의 문제는 정확힌 모르겠지만 string의 메모리가 제대로 해제가 되지 않았거나 벡터에 중복값들이 들어가서 그랬던 것 같다.

 

계속 시행착오를 겪다가 그냥 정렬을 해놓고 0과 1로 이루어진 임시 벡터를 사용해 조합을 한다면 어차피 정렬은 되있기에 자음과 모음의 개수만 체크해주면 되는 문제였다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

vector<string> s;

int main() {
	int l, c, check1 = 0, check2 = 0;
	string a = "";
	cin >> l >> c;
	vector<char> v(c);
	vector<int> temp;
	for (int i = 0; i < c; i++) {
		cin >> v[i];
	}
	for (int i = 0; i < c; i++) {
		if (i < l) {
			temp.push_back(0);
		}
		else {
			temp.push_back(1);
		}
	}
	sort(v.begin(), v.end());
	do {
		a = "";
		check1 = 0, check2 = 0;
		for (int i = 0; i < c; i++) {
			if (temp[i] == 0) {
				a += v[i];
			}
		}
		for (int i = 0; i < a.size(); i++) {
			if (a[i] == 'a' || a[i] == 'e' || a[i] == 'i' 
				|| a[i] == 'o' || a[i] == 'u') {
				check1++;
			}
			else {
				check2++;
			}
		}
		if (check1 >= 1 && check2 >= 2) {
			s.push_back(a);
		}
	} while (next_permutation(temp.begin(), temp.end()));

	for (int i = 0; i < s.size(); i++) {
		cout << s[i] << "\n";
	}

	return 0;
}

www.acmicpc.net/problem/1916

 

1916번: 최소비용 구하기

첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)이 주어지고 둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그

www.acmicpc.net

그냥 단순한 다익스트라 알고리즘을 사용한 문제였다.

 

최근 본 코테에서 다익스트라가 나왔는데도 불구하고 생각이 안나 못풀었던 걸 생각하면ㅠㅠ 미리 왜 공부를 안했나 후회가 되는 문제였다.

 

참고 블로그: alswnsdl.tistory.com/13

 

다익스트라 알고리즘(Dijkstra's algorithm) C++ 코드

다익스트라 알고리즘의 개념은 이전 게시물 http://alswnsdl.tistory.com/12 을 참고 하시면 됩니다. 이번에는 다익스트라 알고리즘의 소스코드에 대해 적어보겠습니다. 다익스트라의 소스코드는 두가

alswnsdl.tistory.com

이 블로그를 통해 우선순위를 이용한 다익스트라 알고리즘을 공부하였고 문제에 적용할 수 있었다.

 

#define _CRT_SECURE_NO_WARNINGS
#define INF 1e9
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
	int V, E, start, end;
	int a, b, c;
	cin >> V >> E;
	vector<pair<int, int>> arr[1001];
	int dist[1001];

	for (int i = 0; i < E; i++) {
		cin >> a >> b >> c;
		arr[a].push_back({ b,c });
	}
	cin >> start >> end;
	fill(dist, dist + V + 1, INF);
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

	pq.push({ 0, start});
	dist[start] = 0;

	while (!pq.empty()) {
		int cost = pq.top().first;
		int here = pq.top().second;
		pq.pop();

		for (int i = 0; i < arr[here].size(); i++) {
			int next = arr[here][i].first;
			int ncost = arr[here][i].second;

			if (dist[next] > dist[here] + ncost) {
				dist[next] = dist[here] + ncost;
				pq.push({ dist[next], next });
			}
		}
	}
	cout << dist[end];
	return 0;
}

참고한 블로그: kiwinam.com/posts/25/android-toolbar-add-button/

 

[안드로이드] 툴바 사용법 - 버튼 추가 :: 키위남

안드로이드 툴바 사용법

kiwinam.com

그전 자바로 프로젝트를 할 때 팀원이 이미 액션바 xml등 모든 세팅을 다 해줬기 때문에 혼자서 개발을 해보았다.

 

어떻게 해야하는 지 막막했는데 위의 블로그를 보고 쉽게 이해할  수 있었다.

 

1. 기존 액션바를 지우고(보통 기본 설정) 액션바를 적용하고자 하는 레이아웃에 툴바를 넣어준다.

 

 

res/values/styles.xml의 style태그를 아래와 같이 수정해 기본 액션바를 설정해준다.

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

 

res/layout루트 아래 xml파일 중 툴바를 넣을 액티비티에 툴바를 넣어준다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

블로그에서는 android.support.v7.widget.Toolbar로 태그 설정이 되어 있었는데 구버전이라 그런 것 같아 나는 신버전인 androidx로 다시 설정해주었다.

 

 

2. Menu.xml을 만들어 액션바 틀을 만들어준다.

 

res/menu에 mainmenu.xml파일을 만들어 주었다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <item
        android:id="@+id/menu_search"
        android:title="search"
        android:icon="@drawable/baseline_search_white_24dp"
        app:showAsAction="always"
        />
    <group>
        <item
            android:id="@+id/menu_account"
            android:title="account"
            />
        <item
            android:id="@+id/menu_logout"
            android:title="logout"
            />
    </group>
</menu>

 

각 icon들은 머티리얼 사이트에서 가져오거나 이미 가지고 있는 파일을 활용하면 된다.

 

 

3. 액티비티에서 툴바를 설정해준다.

 

package com.example.desktop.mymo

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        setSupportActionBar(toolbar)	//툴바 사용 설정

        supportActionBar!!.setDisplayHomeAsUpEnabled(true)	//왼쪽 버튼 사용설정(기본은 뒤로가기)
        supportActionBar!!.setHomeAsUpIndicator(R.drawable.baseline_menu_white_24dp)	//왼쪽 버튼 메뉴로 아이콘 변경
        supportActionBar!!.setDisplayShowTitleEnabled(true)		//타이틀 보이게 설정
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.mainmenu, menu)		//작성한 메뉴파일 설정
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when(item!!.itemId){
            android.R.id.home->{	//각 버튼 마다 스낵바 메세지로 기능 구현
                Snackbar.make(toolbar,"Menu pressed",Snackbar.LENGTH_SHORT).show()
            }
            R.id.menu_search->{
                Snackbar.make(toolbar,"Search Menu pressed",Snackbar.LENGTH_SHORT).show()
            }
            R.id.menu_account->{
                Snackbar.make(toolbar,"Account Menu pressed",Snackbar.LENGTH_SHORT).show()
            }
            R.id.menu_logout->{
                Snackbar.make(toolbar,"Logout Menu pressed",Snackbar.LENGTH_SHORT).show()
            }
        }

        return super.onOptionsItemSelected(item)
    }

}

 

마지막으로 툴바를 사용할 액티비티에 위와 같이 코드를 구성해주면 된다.

 

결과 화면

FAB 기능과 필요없는 코드들은 걷어내고 추가해야할 부분만 코드를 업로드함

material.io/resources/icons/?style=baseline

 

Material Icons

Get Material Icons

material.io

머티리얼 아이콘 사이트에 들어가면 안드로이드 개발에 필요한 대부분의 아이콘을 svg, png 그리고 dp별로 다운로드 받을 수 있다.

 

검은색, 흰색도 정할 수 있고 간단한 add 아이콘부터 시작해서 다양한 아이콘들이 있어서 혼자 개발을 할때 편하게 사용할 수 있다.

 

귀찮게 직접 아이콘을 만들지 말고 다운받아 사용해보자!

 

머티리얼 사이트

 

이와 같이 원하느 아이콘을 검색하고 설정에 맞게 다운이 가능하다.

www.acmicpc.net/problem/1107

 

1107번: 리모컨

첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다.  둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼

www.acmicpc.net

이 문제는 나한테는 너무 악질같은 문제였다.

 

반례도 많은 데다가 런타임 에러까지 발생하니 너무 시간이 오래걸렸다.

 

또한 생각치도 못한 반례가 있어서 결국 못풀다가 답을 보고 풀 수 있었다ㅠㅠ

 

그냥 N*2의 모든 숫자들을 검색해서 최솟값을 찾는 것이 중요한 문제였는데 난 문자열로 바꾸어서 하나씩 비교해가며 찾는 잘못된 방식을 택하고 있었다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;

bool broken[10];

int check(int c) {
	if (c == 0) {
		if (broken[0]) {
			return 0;
		}
		else {
			return 1;
		}
	}
	int len = 0;
	while (c > 0) {
		if (broken[c % 10]) {
			return 0;
		}
		c = c / 10;
		len += 1;
	}
	return len;
}

int main() {
	int n, m, x;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> x;
		broken[x] = true;
	}
	int result = abs(n - 100);
	for (int i = 0; i <= 1000000; i++) {
		int c = i;
		int len = check(c);
		if (len > 0) {
			int press = abs(c - n);
			if (result > press + len) {
				result = press + len;
			}
		}
	}
	cout << result;
	return 0;
}

참고 블로그: seol-limit.tistory.com/48

 

[Baekjoon] 백준 1107번 리모컨

1107번 리모컨 문제 풀이 문제 수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다. 리모컨에는 버튼이 0부터 9까지 숫자, +

seol-limit.tistory.com

 

앱 액션바의 기본 색상을 변경하고 싶었는데 변경 방법이 기억 안나 툴바를 제작할 뻔했다.

 

하지만 잘 찾아보니 colors.xml에 있는 색상을 변경하고 그것을 styles.xml에 적용하면 되는 것이였다.

 

<resources>
    <color name="colorPrimary">#07f5de</color>
    <color name="colorPrimaryDark">#00e8d1</color>
    <color name="colorAccent">#03DAC5</color>
</resources>

액션바 - 상태바 - 버튼색순으로 배치되어 있다.

 

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

각 아이템에 맞는 색상을 집어 넣어 주면 된다.

앱 상단바 색상이 변경됨

위의 세가지 외에 다른 요소들도 각각 색깔을 지정해 줄 수 있는 데 밑의 블로그를 보고 많은 공부가 되었다.

 

iw90.tistory.com/108

 

Android 머티리얼 디자인 색상 변경 하기

Android 머티리얼 디자인 색상 변경 하기 ​​ android 머티리언 디자인 적용에 대해서 전에 포스트를 섰습니다. 정말 간단하게 적용 해서 사용했었는데 이번에는 적용된 머티리얼 디자인 색상을 변

iw90.tistory.com

 

+ Recent posts