반응형

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

 

16928번: 뱀과 사다리 게임

첫째 줄에 게임판에 있는 사다리의 수 N(1 ≤ N ≤ 15)과 뱀의 수 M(1 ≤ M ≤ 15)이 주어진다. 둘째 줄부터 N개의 줄에는 사다리의 정보를 의미하는 x, y (x < y)가 주어진다. x번 칸에 도착하면, y번 칸으

www.acmicpc.net

 

#include <iostream>
#include <queue>
using namespace std;

int dist[101];
int Next[101];

void Solve(){
	dist[1]=0;
	queue<int>q;
	q.push(1);
	while(!q.empty()) {
		int x = q.front();
		q.pop();
		for (int i = 1; i <= 6; i++) {
			int y=x+i;
			if(y>100) continue;
			y=Next[y];
			if(dist[y] == -1){
				dist[y]=dist[x]+1;
				cout<<"i,x,y,dist[y];"<<i<<' '<<x<<' '<<y<<' '<<dist[y]<<endl;
				q.push(y);
			}
		}
	}
	cout<<dist[100]<<endl;
}

void InputData(){
	int n,m;
	cin >> n>>m;
	for(int i=1; i<=100; i++){
		Next[i]=i;
		dist[i]=-1;
	}
	for(int i=1; i<=n+m; i++){
		int x,y;
		cin>>x>>y;
		Next[x]=y;
	}
}

int main(){
	InputData();
	Solve();
	return 0;
}
i,x,y,dist[y];1 1 2 1
i,x,y,dist[y];2 1 3 1
i,x,y,dist[y];3 1 4 1
i,x,y,dist[y];4 1 5 1
i,x,y,dist[y];5 1 6 1
i,x,y,dist[y];6 1 7 1
i,x,y,dist[y];6 2 8 2
i,x,y,dist[y];6 3 9 2
i,x,y,dist[y];6 4 10 2
i,x,y,dist[y];6 5 11 2
i,x,y,dist[y];6 6 98 2
i,x,y,dist[y];6 7 13 2
i,x,y,dist[y];6 8 14 3
i,x,y,dist[y];6 9 15 3
i,x,y,dist[y];6 10 16 3
i,x,y,dist[y];6 11 17 3
i,x,y,dist[y];1 98 99 3
i,x,y,dist[y];2 98 100 3
i,x,y,dist[y];5 13 18 3
i,x,y,dist[y];6 13 19 3
i,x,y,dist[y];6 14 20 4
i,x,y,dist[y];6 15 21 4
i,x,y,dist[y];6 16 22 4
i,x,y,dist[y];6 17 23 4
i,x,y,dist[y];6 18 24 4
i,x,y,dist[y];6 19 25 4
i,x,y,dist[y];6 20 26 5
i,x,y,dist[y];6 21 27 5
i,x,y,dist[y];6 22 28 5
i,x,y,dist[y];6 23 29 5
i,x,y,dist[y];6 24 30 5
i,x,y,dist[y];6 25 31 5
i,x,y,dist[y];6 26 62 6
i,x,y,dist[y];6 27 33 6
i,x,y,dist[y];6 28 34 6
i,x,y,dist[y];6 29 35 6
i,x,y,dist[y];6 30 36 6
i,x,y,dist[y];6 31 37 6
i,x,y,dist[y];1 62 63 7
i,x,y,dist[y];2 62 64 7
i,x,y,dist[y];3 62 65 7
i,x,y,dist[y];4 62 66 7
i,x,y,dist[y];6 62 68 7
i,x,y,dist[y];5 33 38 7
i,x,y,dist[y];6 33 39 7
i,x,y,dist[y];6 34 40 7
i,x,y,dist[y];6 35 41 7
i,x,y,dist[y];6 37 43 7
i,x,y,dist[y];6 63 69 8
i,x,y,dist[y];6 64 70 8
i,x,y,dist[y];6 65 71 8
i,x,y,dist[y];6 66 72 8
i,x,y,dist[y];5 68 73 8
i,x,y,dist[y];6 68 74 8
i,x,y,dist[y];6 38 44 8
i,x,y,dist[y];6 39 45 8
i,x,y,dist[y];6 40 46 8
i,x,y,dist[y];6 41 47 8
i,x,y,dist[y];5 43 48 8
i,x,y,dist[y];6 70 76 9
i,x,y,dist[y];6 71 77 9
i,x,y,dist[y];6 72 78 9
i,x,y,dist[y];6 74 80 9
i,x,y,dist[y];6 44 50 9
i,x,y,dist[y];6 45 51 9
i,x,y,dist[y];6 46 52 9
i,x,y,dist[y];6 47 53 9
i,x,y,dist[y];6 48 54 9
i,x,y,dist[y];5 76 81 10
i,x,y,dist[y];6 76 82 10
i,x,y,dist[y];6 77 83 10
i,x,y,dist[y];6 78 84 10
i,x,y,dist[y];5 80 85 10
i,x,y,dist[y];6 80 86 10
i,x,y,dist[y];5 50 55 10
i,x,y,dist[y];6 50 56 10
i,x,y,dist[y];6 51 57 10
i,x,y,dist[y];6 52 58 10
i,x,y,dist[y];6 53 59 10
i,x,y,dist[y];6 54 60 10
i,x,y,dist[y];6 81 87 11
i,x,y,dist[y];6 82 88 11
i,x,y,dist[y];6 83 89 11
i,x,y,dist[y];6 84 90 11
i,x,y,dist[y];6 85 91 11
i,x,y,dist[y];6 86 92 11
i,x,y,dist[y];6 55 61 11
i,x,y,dist[y];6 88 94 12
i,x,y,dist[y];6 90 96 12
3
반응형

'Algorithm > BFS,DFS' 카테고리의 다른 글

[C++][BFS]백준 2589 보물섬  (0) 2022.04.11
[C++][백준]1520 내리막길  (0) 2022.04.10
[C++][백준]14502 연구소  (0) 2022.04.10
[C++][백준]적록색약  (0) 2022.04.10
[c++][algoritm][baekjoon]7562 나이트의 이동  (0) 2021.09.23
반응형

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

 

1912번: 연속합

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

 

[풀이]

-다이나믹 프로그래밍으로 풀수 있다. 

#include <iostream>
#define MAXN 100010
using namespace std;
int N;//입력 갯수 
int A[MAXN];//입력 데이타 저장할 배열 
int dp[MAXN];//다이나믹 프로그래밍 저장용 배열 
 
void Solve(){
    dp[1] = A[1];
    int sol = dp[1];
    for (int i = 2; i <= N; i++){
        dp[i] = max(A[i], dp[i-1] + A[i]);
        if(sol<dp[i])  sol= dp[i];
    }
    cout << sol << endl;
}
 
void InputData(){
    cin >> N;
    for(int i = 1; i <= N; i++) cin >> A[i];
}
int main(void){
	InputData();
    Solve();
    return 0;
}

 

- dfs로 풀수 있다. 

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 100010
int N;
int D[MAXN];
int max_sum=(1<<31);
void dfs(int n, int sum){
	if(n>N) return;
	max_sum=max(max(max_sum,D[n]),sum);

	if(D[n]>sum){
		sum=0;
		n--;
	}
	dfs(n+1,sum+D[n+1]);
}
void InputData(){
	cin>>N;
	for(int i=1; i<=N; i++)
		cin>>D[i];
}
int main(){
	InputData();
	dfs(1,D[1]);
	return 0;
}
반응형
반응형

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

 

1912번: 연속합

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

 

[풀이]

-다이나믹 프로그래밍으로 풀수 있다. 

#include <iostream>
#define MAXN 100010
using namespace std;
int N;//입력 갯수 
int A[MAXN];//입력 데이타 저장할 배열 
int dp[MAXN];//다이나믹 프로그래밍 저장용 배열 
 
void Solve(){
    dp[1] = A[1];
    int sol = dp[1];
    for (int i = 2; i <= N; i++){
        dp[i] = max(A[i], dp[i-1] + A[i]);
        if(sol<dp[i])  sol= dp[i];
    }
    cout << sol << endl;
}
 
void InputData(){
    cin >> N;
    for(int i = 1; i <= N; i++) cin >> A[i];
}
int main(void){
	InputData();
    Solve();
    return 0;
}

 

- dfs로 풀수 있다. 

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 100010
int N;
int D[MAXN];
int max_sum=(1<<31);
void dfs(int n, int sum){
	if(n>N) return;
	max_sum=max({max_sum,D[n],sum});

	if(D[n]>sum){
		sum=0;
		n--;
	}
	dfs(n+1,sum+D[n+1]);
}
void InputData(){
	cin>>N;
	for(int i=1; i<=N; i++)
		cin>>D[i];
}
int main(){
	InputData();
	dfs(1,D[1]);
    cout<<max_sum<<endl;
	return 0;
}
반응형
반응형

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

 

[문제풀이]

1.BFS로 풀수 있다. 

2.L:육지로 이동가능한곳, W:물로 이동할 수 없다 

3.L만 찾아서 1개씩 큐에 저장후 이동할 수 있는 가장 먼 거리를 찾는 문제이다.

4.map정보가 같은 크기의 visited배열을 만들어서 방문 기록을 하고 매번 초기화 해줘야한다.

 

#include <iostream>
#include <queue>
#include <memory.h>
using namespace std;
#define MAXN (50)
int N, M;//세로, 가로
char map[MAXN+10][MAXN+10];//지도정보
int visited[MAXN+10][MAXN+10];//방문 표시 
struct Q{
	int y,x,t;
};
int count=0,ans=-1;
int BFS(int y, int x,int t){
	queue<Q>q;
	int dy[]={-1,1,0,0};//동서남북
	int dx[]={0,0,-1,1};
	//1.초기화 
	count=0;
	q={};
	//2.큐에 초기값 저장 
	q.push({y,x,t});	
	//3.반복문 
	while(!q.empty()){
		Q cur=q.front();q.pop();
		visited[y][x]=1;

		for(int i=0; i<4; i++){
			t=cur.t;
			int ny=cur.y+dy[i];
			int nx=cur.x+dx[i];
			if((ny<0) || (ny>=N) || (nx<0) || (nx>=M) || map[ny][nx]!='L') continue;
			if(visited[ny][nx]==0){
				visited[ny][nx]=1;
				q.push({ny,nx,t+1});
				count=t+1;
				if(ans<count) ans=count;//ans에 최대값 업데이트 
			}
		}
	}
	return ans;
}
void Solve(){
	for (int i=0; i<N; i++){
		for (int j=0; j<M; j++){
			if(map[i][j]=='L'){
				ans=BFS(i,j,0);
				memset(visited,false,sizeof(visited));
			}
		}
	}
	cout<<ans<<endl;
}
void InputData(){
	cin>>N>>M;
	for (int i=0; i<N; i++){
		cin>>map[i];
	}
}
int main(){
	InputData();
	Solve();
	return 0;
}
반응형

'Algorithm > BFS,DFS' 카테고리의 다른 글

[c++][백준]뱀과 사다리  (0) 2022.05.16
[C++][백준]1520 내리막길  (0) 2022.04.10
[C++][백준]14502 연구소  (0) 2022.04.10
[C++][백준]적록색약  (0) 2022.04.10
[c++][algoritm][baekjoon]7562 나이트의 이동  (0) 2021.09.23
반응형

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

 

1520번: 내리막 길

첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다.

www.acmicpc.net

 

[문제풀이]

1.dfs를 이용해서 푸는 문제이다.

2.최종 출력값은 visited[0][0]=3이 정답인데, visited[N-1][M-1]의 값이 정답으로 생각했는데, 의외인것 같다.

입력과 좌표에 따른 visited값

/*1520 내리막길 */
#include<iostream>
#include<memory.h>
using namespace std;

#define MAXN (int)5e2+10
int M,N;//행,열 
int map[MAXN][MAXN];
int visited[MAXN][MAXN]={0,};//방문 표시
int dy[]={-1,1,0,0};//상하좌우
int dx[]={0,0,-1,1};
bool isInside(int a, int b){
	return ( (a>=0) && (a<M) && (b>=0) && (b<N));
}
int DFS(int y, int x){
	if(y==M-1 && x==N-1) return 1;
	if(visited[y][x]!=-1) return visited[y][x];
	visited[y][x]=0;
	for(int i=0; i<4; i++){
		int ny=y+dy[i];
		int nx=x+dx[i];
		if(isInside(ny,nx)){
			if(map[ny][nx]<map[y][x])
				visited[y][x]+=DFS(ny,nx);
		}
	}
	return visited[y][x];
}
void InputData(){
	cin>>M>>N;
	for(int i=0; i<M; i++){
		for(int j=0; j<N; j++){
			cin>>map[i][j];
		}
	}
	memset(visited,-1,sizeof(visited));
}
int main(){
	InputData();
	cout<<DFS(0,0);
	return 0;
}
반응형

'Algorithm > BFS,DFS' 카테고리의 다른 글

[c++][백준]뱀과 사다리  (0) 2022.05.16
[C++][BFS]백준 2589 보물섬  (0) 2022.04.11
[C++][백준]14502 연구소  (0) 2022.04.10
[C++][백준]적록색약  (0) 2022.04.10
[c++][algoritm][baekjoon]7562 나이트의 이동  (0) 2021.09.23
반응형

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

 

[풀이과정]

1.바이러스 걸린 방의 위치 저장 해 둔다, 여기서는 vector를 사용했다.

   배열을 사용해서 저장해도 되는데 사이즈를 따로 관리해야하는 번거로움이 있어서 vector를 이용했다.

   BFS에서 사용할 queue에 저장해서 넘겨주면 될 것 같지만 그렇게 되면 BFS가 한번 돌고 나면 queue에서 사라지므로 

   변형되지 않는 곳을 만들어서 저장해 두어야 한다.

2.3가지 종류의 벽의 조합을 모두 만들어야 하므로 DFS를 사용해야 한다.

3.벽을 만든 후에는 vector에 저장된 바이러스가 퍼지는 는 맵을 완성한다.

4.바이러스가 모두 퍼진 후 전염되지 않은 방의 갯수를 센다.

5.2번부터 다시 반복해서 바이러스가 전염되지 않은 방 갯수 중 가장 큰 경우를 찾으면 된다. 

 

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

int N,M;//행,열 
int map[8][8];
int tmp[8][8];//방문 표시
int dy[]={-1,1,0,0};//상하좌우
int dx[]={0,0,-1,1};
struct Q{
	int y,x;
};
queue<Q>q;
vector<Q>v;
int sol=0;
bool isInside(int a, int b){
	return ( (a>=0) && (a<N) && (b>=0) && (b<M));
}
int BFS(){	
	int count=0;
	//1.큐 초기화 
	q={};
	//2.큐에 초기값 입력 
    for(int i = 0; i < v.size(); i++)
        q.push(v[i]);
	//3.반복문 
	while(!q.empty()){
		Q cur=q.front();q.pop();
		for(int i=0; i<4; i++){
			int ny=cur.y+dy[i];
			int nx=cur.x+dx[i];
			if(isInside(ny,nx) && tmp[ny][nx]==0){
				tmp[ny][nx]=2;
				q.push({ny,nx});
			}	
		}
	}
	//4.return할 값 
	for(int i=0; i<N; i++){
		for(int j=0; j<M; j++){
			if(tmp[i][j]==0)
				count++;
		}
	}
	return count;
}
void copymap(){
	for(int i=0; i<N; i++){
		for(int j=0; j<M; j++){
			tmp[i][j]=map[i][j];
		}
	}
}
	
void DFS(int x, int d){
	if(d==3){
		copymap();//기존 map을 훼손하면 안되므로 임시 map에 저장함 
		sol=max(sol,BFS());//감염되지 않은 방중 최대값으로 업데이트 
		return;
	}
	for(int i=x; i<N; i++){
		for(int j=0; j<M; j++){
			if(map[i][j]==0){
				map[i][j]=1;
				DFS(i,d+1);
				map[i][j]=0;
			}
		}
	}

}
void Solve(){
	DFS(0,0);//맵에서 벽을 세울수 있는 경우를 DFS를 이용해서 조합으로 만듬
	cout<<sol<<endl;//오염되지 않은 방중 가장 큰값 
}
void InputData(){
	cin>>N>>M;
	for(int i=0; i<N; i++){
		for(int j=0; j<M; j++){
			cin>>map[i][j];
			if(map[i][j]==2){
				v.push_back({i,j});//바이러스 걸린 방을 따로 저장해 두어야한다. 
			}
		}
	}
}
int main(){
	InputData();
	Solve();
	return 0;
}
반응형

'Algorithm > BFS,DFS' 카테고리의 다른 글

[C++][BFS]백준 2589 보물섬  (0) 2022.04.11
[C++][백준]1520 내리막길  (0) 2022.04.10
[C++][백준]적록색약  (0) 2022.04.10
[c++][algoritm][baekjoon]7562 나이트의 이동  (0) 2021.09.23
[c++][algorithm][baekjoon][7569]토마토  (0) 2021.08.29
반응형

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

 

[풀이과정]

1.R,G,B 각 글자에 대해서 FloodFill을 이용해서 글자가 상하좌우에 연결된 부분을 찾는다.

2.전체 맵을 각 글자의 묶음들이 있는 걸 count해서 R,G,B 각 글자에 대해서 숫자를 count한다.

3.적록 색맹을 경우는 R를 G로 변경하는 작업을 해 준다.

4.1번 부터 동일한 과정으로 R,G에 대한 count를 해주면 된다.

/*백준 10026 적록색약*/
#include<iostream>
#include<memory.h>
using namespace std;
#define MAXN (int)1e2+10
char map[MAXN][MAXN];
int visited[MAXN][MAXN];//방문 표시
int N;//행,열 
int dy[]={-1,1,0,0};
int dx[]={0,0,-1,1};
bool isInside(int a, int b){
	return ( (a>=0) && (a<N) && (b>=0) && (b<N));
}
bool DFS(int y, int x, char c){	
	
	if(isInside(y,x) && visited[y][x]==0 && map[y][x]==c){
		visited[y][x]=1;
		for(int i=0; i<4; i++){
			DFS(y+dy[i],x+dx[i],c);
			//cout<<y+dy[i]<<' '<<x+dx[i]<<endl;
		}	
		return true;
	}else{
		return false;
	}
}
int Calc(int c){
	int cnt=0;
	for(int i=0; i<N; i++){
		for(int j=0; j<N; j++){
			if(map[i][j]==c)
				cnt+=DFS(i,j,c);
		}
	}
	return cnt;
}
void remap(){
	for(int i=0; i<N; i++){
		for(int j=0; j<N; j++){
			if(map[i][j]=='R')
				map[i][j]='G';
		}
	}
}
void Solve(){
	int cnt1=0,cnt2=0;
	cnt1+=Calc('R');
	cnt1+=Calc('G');
	cnt1+=Calc('B');
	memset(visited,false,sizeof(visited));
	remap();
	cnt2+=Calc('G');
	cnt2+=Calc('B');
	cout<<cnt1<<' '<<cnt2<<endl;
}
void InputData(){
	cin>>N;
	for(int i=0; i<N; i++){
			cin>>map[i];
	}
}
int main(){
	InputData();
	Solve();
	return 0;
}
반응형
반응형

문제

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.

예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {1020, 10, 30, 20, 50} 이고, 길이는 4이다.

입력

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.

둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

출력

 

첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.

 
예제 입력 1 
6
10 20 10 30 20 50
예제 출력 1 
4

8
10 20 30 5 10 20 30 40
정답: 5

반례 추가 
10
4 7 10 3 1 8 7 2 5 7
Answer: 4 
7
7 9 10 8 2 3 7
Answer: 3 
10
7 10 8 10 1 2 9 9 1 10
Answer: 4 
9
2 8 3 10 5 1 5 2 3
Answer: 3 
10
10 6 5 9 10 9 3 4 7 1
Answer: 3 
10
5 8 10 3 9 1 5 8 5 6
Answer: 3 
9
3 2 8 2 10 1 2 2 3
Answer: 3 
10
3 8 10 1 5 7 9 8 9 6
Answer: 5
7
4 3 4 9 1 3 7
Answer: 3 
10
8 6 8 9 5 1 4 4 6 3
Answer: 3

 

/*[12015]가장 긴 증가하는 부분 수열2*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int)1e6+10)
int N; 
int A[MAXN];
vector<int> v;
auto it = v.begin();
void InputData(){
    cin >> N;
    for(int i=0; i<N; i++){
        cin >> A[i];
    }
}
void Solve(){
    v.push_back(A[0]);
    for(int i=1; i<N; i++){
        if(v.back() < A[i] ) v.push_back(A[i]);
        else {
            it = v.begin();
            it = lower_bound(v.begin(), v.end(), A[i]);
            *it = A[i];
        } 
    }
    cout << v.size() << endl;
}
int main(){
    InputData();
    Solve();
    return 0;
}
/*[12015]가장 긴 증가하는 부분 수열2*/
반응형
반응형

문제

세준이는 크기가 N×N인 배열 A를 만들었다. 배열에 들어있는 수 A[i][j] = i×j 이다. 이 수를 일차원 배열 B에 넣으면 B의 크기는 N×N이 된다. B를 오름차순 정렬했을 때, B[k]를 구해보자.

배열 A와 B의 인덱스는 1부터 시작한다.

입력

첫째 줄에 배열의 크기 N이 주어진다. N은 105보다 작거나 같은 자연수이다. 둘째 줄에 k가 주어진다. k는 min(109, N2)보다 작거나 같은 자연수이다.

출력

B[k]를 출력한다.

예제 입력 1 
3
7
예제 출력 1 
6

 

3
7
i: 1 lo:1 hi : 7 mid: 4 tmp: 3
i: 2 lo:1 hi : 7 mid: 4 tmp: 5
i: 3 lo:1 hi : 7 mid: 4 tmp: 6
i: 1 lo:5 hi : 7 mid: 6 tmp: 3
i: 2 lo:5 hi : 7 mid: 6 tmp: 6
i: 3 lo:5 hi : 7 mid: 6 tmp: 8
i: 1 lo:5 hi : 5 mid: 5 tmp: 3
i: 2 lo:5 hi : 5 mid: 5 tmp: 5
i: 3 lo:5 hi : 5 mid: 5 tmp: 6
6

반응형
반응형

문제

도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.

도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.

C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.

 

입력

첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가 한 줄에 하나씩 주어진다.

출력

첫째 줄에 가장 인접한 두 공유기 사이의 최대 거리를 출력한다.

 

예제입력1
5 3
1
2
8
4
9

예제출력1
3

 

N : 집의 개수 

C : 공유기 개수 

이후 집의 좌표 

 

N : 3, C: 3

집의 좌표를 먼저 오름차순으로 정렬한다.

1 2 4 8 9

5 3
1
2
8
4
9
i: 1 X[i] : 2 lo:1 hi : 8 mid: 4 start: 1 cnt :1
i: 2 X[i] : 4 lo:1 hi : 8 mid: 4 start: 1 cnt :1
i: 3 X[i] : 8 lo:1 hi : 8 mid: 4 start: 8 cnt :2
i: 4 X[i] : 9 lo:1 hi : 8 mid: 4 start: 8 cnt :2
i: 1 X[i] : 2 lo:1 hi : 3 mid: 2 start: 1 cnt :1
i: 2 X[i] : 4 lo:1 hi : 3 mid: 2 start: 4 cnt :2
i: 3 X[i] : 8 lo:1 hi : 3 mid: 2 start: 8 cnt :3
i: 4 X[i] : 9 lo:1 hi : 3 mid: 2 start: 8 cnt :3
i: 1 X[i] : 2 lo:3 hi : 3 mid: 3 start: 1 cnt :1
i: 2 X[i] : 4 lo:3 hi : 3 mid: 3 start: 4 cnt :2
i: 3 X[i] : 8 lo:3 hi : 3 mid: 3 start: 8 cnt :3
i: 4 X[i] : 9 lo:3 hi : 3 mid: 3 start: 8 cnt :3
3

 

/*[2110]공유기 설치*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int)2e5+10)
int N,C; //집의 개수, 공유기개수 
int X[MAXN];
long long M;

void InputData(){
    cin >> N >> C;
    for(int i =0; i<N; i++){
        cin >> X[i];
    }
}
void Solve(){
    int lo, hi, mid;
    long long sum;
    sort(X,X+N);
    lo = 1;
    hi = X[N-1] - X[0];
    int d = 0;
    int ans = 0;
    while(lo <= hi){
        mid=(lo+hi)/2; 
        int start = X[0];
        int cnt = 1;
        for(int i=1; i<N; i++){
            d = X[i] - start;
            if(mid <= d){
                ++cnt;
                start = X[i];
            }
       cout << "i: " << i << " X[i] : " << X[i] << " lo:" <<  lo  << " hi : " << hi  <<  " mid: " << mid <<  " start: " << start << " cnt :" << cnt  << endl;
         }
        if( cnt >= C){
            ans = mid;
            lo = mid + 1;
        }else{
            hi = mid - 1;
        }

        }
    cout << ans << endl;
}
int main(){
    InputData();
    Solve();
    return 0;
}
/*[2110]공유기 설치*/
반응형
반응형

문제

상근이는 나무 M미터가 필요하다. 근처에 나무를 구입할 곳이 모두 망해버렸기 때문에, 정부에 벌목 허가를 요청했다. 정부는 상근이네 집 근처의 나무 한 줄에 대한 벌목 허가를 내주었고, 상근이는 새로 구입한 목재절단기를 이용해서 나무를 구할것이다.

목재절단기는 다음과 같이 동작한다. 먼저, 상근이는 절단기에 높이 H를 지정해야 한다. 높이를 지정하면 톱날이 땅으로부터 H미터 위로 올라간다. 그 다음, 한 줄에 연속해있는 나무를 모두 절단해버린다. 따라서, 높이가 H보다 큰 나무는 H 위의 부분이 잘릴 것이고, 낮은 나무는 잘리지 않을 것이다. 예를 들어, 한 줄에 연속해있는 나무의 높이가 20, 15, 10, 17이라고 하자. 상근이가 높이를 15로 지정했다면, 나무를 자른 뒤의 높이는 15, 15, 10, 15가 될 것이고, 상근이는 길이가 5인 나무와 2인 나무를 들고 집에 갈 것이다. (총 7미터를 집에 들고 간다) 절단기에 설정할 수 있는 높이는 양의 정수 또는 0이다.

상근이는 환경에 매우 관심이 많기 때문에, 나무를 필요한 만큼만 집으로 가져가려고 한다. 이때, 적어도 M미터의 나무를 집에 가져가기 위해서 절단기에 설정할 수 있는 높이의 최댓값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000)

둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보다 크거나 같기 때문에, 상근이는 집에 필요한 나무를 항상 가져갈 수 있다. 높이는 1,000,000,000보다 작거나 같은 양의 정수 또는 0이다.

 

출력

적어도 M미터의 나무를 집에 가져가기 위해서 절단기에 설정할 수 있는 높이의 최댓값을 출력한다.

 

4 7
20 15 10 17
출력 : 15

5 20
4 42 40 26 46
출력:36

2 11
10 10
출력 : 4

3 1
1 2 2
출력 : 1
 
4 10
1 4 5 7
출력:2

5 2000000000
900000000 900000000 900000000 900000000 900000000
출력: 500000000

1 1000000000
1000000000
출력: 0

1 1
1000000000
출력: 999999999

6 12
19 9 18 20 17 8
출력: 15
 
5 14
4 22 10 16 36
출력: 22

풀이 과정 

나무수 N이 1,000,000개 이어서 이진 탐색으로 해서 찾아야 시간 초과 발생하지 않고 해결이 된다고 추측할 수 있다.

이진탐색색을 하기 위해서는 찾고자 하는 데이타를 오름차순 정렬을 해야 한다.

여기서 데이타는 나무 높이 데이타인 A를 정령해야 한다.

lo,hi값을 선정해야하는데, sorting후 제일 작은 값과 제일 큰 값으로 선정하면 된다. 

 

/*[2805]나무자르기*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int)1e6+10)
int N;
int A[MAXN +10];
long long M;

void Solve(){
    int lo, hi, mid,sol=0;
    long long sum;
    sort(A,A+N);
    lo = 1;
    hi = A[N-1];
    while(lo <= hi){
        sum=0;
        mid=(lo+hi)/2; 
        for(int i=0; i<N; i++){
            if(A[i] > mid) sum += (A[i] - mid);
        }
        if(sum >= M){
            sol=mid;
            lo=mid+1;
        }else{
           hi = mid-1; 
        }
    }
    cout << sol << endl;
}
void InputData(){
    cin >> N >> M;
    for(int i =0; i<N; i++){
        cin >> A[i];
    }
}
int main(){
    InputData();
    Solve();
    return 0;
}
/*[2805]나무자르기*/
반응형
반응형

[2438]별 찍기 - 1

예제 입력 1 
5

예제 출력 1 
*
**
***
****
*****
#include <bits/stdc++.h>
using namespace std;
int main()
{
  int N;
  cin >> N;

  for(int i=1; i<=N; i++){
    for(int j=1; j<=i; j++){
       printf("*");
    }
    cout << endl;
  }
  return 0;
}

 

[2439]별 찍기 - 2

예제 입력 1 
5
예제 출력 1 
    *
   **
  ***
 ****
*****
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int N;
  cin >> N;

  for(int i=1; i<=N; i++){
    for(int k=1; k<=N-i; k++){
      cout << " ";
    }
    for(int j=1; j<=i; j++){
      cout << "*";
    }
    cout << endl;
  }
  return 0;
}

[2440]별 찍기 - 3

예제 입력 1 
5
예제 출력 1 
*****
****
***
**
*
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int N;
  cin >> N;

  for(int i=0; i<N; i++){
    for(int j=0; j<N-i; j++){
      cout << "*";
    }
    cout << endl;
  }
  return 0;
}

[2441]별 찍기 - 4

예제 입력 1 
5
예제 출력 1 
*****
 ****
  ***
   **
    *
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int N;
  cin >> N;

  for(int i=0; i<N; i++){
    for(int k=0; k<i; k++){
      cout << " ";
    }
    for(int j=0; j<N-i; j++){
      cout << "*";
    }
    cout << endl;
  }
  return 0;
}

[2442]별 찍기 - 5

예제 입력 1 
5
예제 출력 1 
    *
   ***
  *****
 *******
*********

 

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

int main()
{
  int N;
  cin >> N;

  for(int i=1; i<=N; i++){
    for(int k=1; k<=N-i; k++){
      cout << " ";
    }
    for(int j=1; j<=2*i-1; j++){
      cout << "*";
    }
    cout << endl;
  }
  return 0;
}

[2443]별 찍기 - 6

예제 입력 1 
5
예제 출력 1 
*********
 *******
  *****
   ***
    *
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int N;
  cin >> N;

  for(int i=0; i<N; i++){
    for(int k=0; k<i; k++){
      cout << " ";
    }
    for(int j=0; j<2*(N-i)-1; j++){
      cout << "*";
    }
    cout << endl;
  }
  return 0;
}

[2444]별 찍기 - 7

예제 입력 1 
5
예제 출력 1 
    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *
반응형

'Algorithm > 구현-기하학' 카테고리의 다른 글

[c++]baekjoon 2477 참외밭  (0) 2021.06.05
[c++]baekjoon 2166 다각형의 면적  (0) 2021.06.05
반응형

2747 피보나치 수

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 45보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

풀이 

아래 코드 입력 시 시간 초과 발생한다. 

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

int fibo(int a)
{
    if( a == 0) 
        return 0;
    else if(a ==1)
        return 1;
    else
        return (fibo(a-1) + fibo(a-2));
}

int main()
{
    int repeat; 
    cin >> repeat;
	cout << fibo(repeat);

	return 0;
}

아래와 같이 dynamic programming방식으로 풀어서 시간초과를 없앴다.

/*[baekjoon][2747] 피보나치 수*/
#include <bits/stdc++.h>
using namespace std;
int d[50];

int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2747] 피보나치 수*/

 

2748 피보나치 수 2

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 90보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

/*[baekjoon][2748] 피보나치 수 2*/
#include <bits/stdc++.h>
using namespace std;
long long int d[100];

long long int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2748] 피보나치 수 2*/

 

2749 피보나치 수 3

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 1,000,000으로 나눈 나머지를 출력한다.

예제 입력 1 복사

1000

예제 출력 1 복사

228875

반응형
반응형

2747 피보나치 수

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 45보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

풀이 

아래 코드 입력 시 시간 초과 발생한다. 

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

int fibo(int a)
{
    if( a == 0) 
        return 0;
    else if(a ==1)
        return 1;
    else
        return (fibo(a-1) + fibo(a-2));
}

int main()
{
    int repeat; 
    cin >> repeat;
	cout << fibo(repeat);

	return 0;
}

아래와 같이 dynamic programming방식으로 풀어서 시간초과를 없앴다.

/*[baekjoon][2747] 피보나치 수*/
#include <bits/stdc++.h>
using namespace std;
int d[50];

int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2747] 피보나치 수*/

 

2748 피보나치 수 2

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 90보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

/*[baekjoon][2748] 피보나치 수 2*/
#include <bits/stdc++.h>
using namespace std;
long long int d[100];

long long int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2748] 피보나치 수 2*/

 

2749 피보나치 수 3

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 1,000,000으로 나눈 나머지를 출력한다.

예제 입력 1 복사

1000

예제 출력 1 복사

228875

반응형
반응형

2747 피보나치 수

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 45보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

풀이 

아래 코드 입력 시 시간 초과 발생한다. 

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

int fibo(int a)
{
    if( a == 0) 
        return 0;
    else if(a ==1)
        return 1;
    else
        return (fibo(a-1) + fibo(a-2));
}

int main()
{
    int repeat; 
    cin >> repeat;
	cout << fibo(repeat);

	return 0;
}

아래와 같이 dynamic programming방식으로 풀어서 시간초과를 없앴다.

/*[baekjoon][2747] 피보나치 수*/
#include <bits/stdc++.h>
using namespace std;
int d[50];

int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2747] 피보나치 수*/

 

2748 피보나치 수 2

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 90보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

예제 입력 1 복사

10

예제 출력 1 복사

55

 

/*[baekjoon][2748] 피보나치 수 2*/
#include <bits/stdc++.h>
using namespace std;
long long int d[100];

long long int fibonacci(int n)
{
    if( n == 0) return 0; 
    else if(n ==1) return 1;
    else if(d[n] != 0) return d[n];
    return d[n]=(fibonacci(n-1) + fibonacci(n-2));
}

int main()
{
    int n; 
    cin >> n;
	cout << fibonacci(n);

	return 0;
}
/*[baekjoon][2748] 피보나치 수 2*/

 

2749 피보나치 수 3

더보기
더보기

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 1,000,000으로 나눈 나머지를 출력한다.

예제 입력 1 복사

1000

예제 출력 1 복사

228875

반응형
반응형
더보기

문제

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.

상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.

상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. (3 ≤ N ≤ 5000)

출력

상근이가 배달하는 봉지의 최소 개수를 출력한다. 만약, 정확하게 N킬로그램을 만들 수 없다면 -1을 출력한다.

예제 입력 1 
18
예제 출력 1 
4
예제 입력 2 
4
예제 출력 2 
-1
예제 입력 3 
6
예제 출력 3 
2
예제 입력 4 
9
예제 출력 4 
3
예제 입력 5 
11
예제 출력 5 
3

 

이 문제는 동적 계획법 문제로 풀어야 한다. 

 

/*baekjoon 2839 설탕 배달*/
#include <iostream>
using namespace std;
int N; // 설탕 무게 

void InputData(){
    cin >> N;
}
void Solve()
{
    int total = 0;
    int tmp = 0;

    if( N%5 == 0 ){
        cout <<  N/5 << endl;
    }else{
        tmp = N/5;
        do{
            if((N - tmp*5)%3 == 0){
                cout << tmp + (N -5*tmp)/3 << endl;
                break; 
            }
            tmp--;
            }while(tmp >=0 );
    }
    if( tmp == -1 )
    cout << "-1" << endl;
}
int main()
{
    InputData();
    Solve();
    return 0;
}
/*baekjoon 2839 설탕 배달*/
반응형

'Algorithm > 동적계획법(dynamic programming)' 카테고리의 다른 글

[c++][baekjoon]1912 연속합  (0) 2022.05.09
[c++][baekjoon]1912 연속합  (0) 2022.05.08
반응형

문제

체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까?

입력

입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다.

각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 l(4 ≤ l ≤ 300)이 주어진다. 체스판의 크기는 l × l이다. 체스판의 각 칸은 두 수의 쌍 {0, ..., l-1} × {0, ..., l-1}로 나타낼 수 있다. 둘째 줄과 셋째 줄에는 나이트가 현재 있는 칸, 나이트가 이동하려고 하는 칸이 주어진다.

출력

각 테스트 케이스마다 나이트가 최소 몇 번만에 이동할 수 있는지 출력한다.

 

예제 입력 1 
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1

예제 출력 1 
5
28
0

 

풀이

1)입력은

T: 테스트 케이스 

N : 체스판의 한변의 길이

sy,sx : 나이트 시작 좌표

ey,ex : 나이트 목적지 좌표 

2)풀이 핵심은 

dy,dx를 그림과 같이 이동하는 경우를 모두 표시해 두는 게 가장 중요하다. 

그리고 나머지는 기존 bfs를 이용한 방법과 동일 하다 

/*[baekjoon]7562 나이트의 이동*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int) 3e2)
int Map[MAXN+10][MAXN+10];
bool visited[MAXN+10][MAXN+10];
int T;//test case
int N;//Map size
int sy,sx,ey,ex;
int dy[]={2,1,2,1,-2,-1,-2,-1};
int dx[]={1,2,-1,-2,-1,-2,1,2};
bool inRange(int x, int y){
    return ( (x>=0) && (x<N) && (y>=0) && (y<N));
}

void BFS(int y, int x){
    int ny,nx;
    queue <pair<int,int>> q;
    q.push(make_pair(y,x));
    visited[y][x]=true;

    while(!q.empty()){
        y=q.front().first;
        x=q.front().second;
        q.pop();
        if((y==ey) && (x==ex)) break;
        for(int i=0; i<8; i++){
            ny=y+dy[i];
            nx=x+dx[i];
            if(inRange(ny,nx) && !visited[ny][nx]){
                visited[ny][nx]=true;
                Map[ny][nx]=Map[y][x]+1;
                q.push(make_pair(ny,nx));
            }
        }

    }

}
void InputData(){
    cin >> T;
}
void Solve(){
    for(int i=0; i<T; i++){
        cin >> N;
        cin >> sy >> sx >> ey >> ex ;
        BFS(sy,sx);
        cout << Map[ey][ex] << endl;
        memset(Map, false, sizeof(Map));
        memset(visited, false, sizeof(visited));
    }
}
int main(){
   InputData();
   Solve();
   return 0;
}
/*[baekjoon]7562 나이트의 이동*/
반응형
반응형

문제

철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이 격자모양 상자의 칸에 하나씩 넣은 다음, 상자들을 수직으로 쌓아 올려서 창고에 보관한다.

창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토에 인접한 곳은 위, 아래, 왼쪽, 오른쪽, 앞, 뒤 여섯 방향에 있는 토마토를 의미한다. 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지 그 최소 일수를 알고 싶어 한다.

토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라. 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.

입력

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100, 1 ≤ H ≤ 100 이다. 둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 하나의 상자에 담긴 토마토의 정보가 주어진다. 각 줄에는 상자 가로줄에 들어있는 토마토들의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0 은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다. 이러한 N개의 줄이 H번 반복하여 주어진다.

토마토가 하나 이상 있는 경우만 입력으로 주어진다.

출력

여러분은 토마토가 모두 익을 때까지 최소 며칠이 걸리는지를 계산해서 출력해야 한다. 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, 토마토가 모두 익지는 못하는 상황이면 -1을 출력해야 한다.

 

예제 입력 1 
5 3 1
0 -1 0 0 0
-1 -1 0 1 1
0 0 0 1 1
예제 출력 1 
-1

예제 입력 2 
5 3 2
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
예제 출력 2 
4

예제 입력 3 
4 3 2
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
-1 -1 -1 -1
1 1 1 -1
예제 출력 3 
0

풀이 

1. 입력 : 1인 모든 좌표를 queue에 push

2. queue에서 하나씩 꺼내서 상하좌우,위,아래 6개 방향을 확인해서 1이 있는 지 확인한다.

3. 

/*baekjoon 7569 토마토 BFS*/
#include <iostream>
#include <queue>
using namespace std;
#define max ((int)1e2+5)

int M,N,H ;//가로, 세로,상자수 
int map[max][max][max];
bool mapCheck[max][max][max];
int path[max][max][max];
int cnt;
int dz[6] = {0,0,0,0,-1,1};
int dy[6] = {-1,1,0,0,0,0};
int dx[6] = {0,0,1,-1,0,0};
struct Q{
	int z,y,x;
};
Q cur;
queue<Q>q;

bool isInside(int z, int y,int x){
    return ((z>=0 && z<H) && (y>=0 && y<N) && (x>=0 && x<M));
}

void Solve(){
    int nx,ny,nz;
    while(!q.empty()) {
        cur=q.front();
        q.pop();

        for (int i = 0; i < 6; i++) {
            nz = cur.z + dz[i];
            ny = cur.y + dy[i];
            nx = cur.x + dx[i];

            if(isInside(nz,ny,nx) && map[nz][ny][nx]==0 && mapCheck[nz][ny][nx]==0 ){
                mapCheck[nz][ny][nx] = 1;
                q.push({nz,ny,nx});
                path[nz][ny][nx] = path[cur.z][cur.y][cur.x] + 1;
            }
        }
    }
}
void InputData(){
    cin >> M >> N >> H;
    for( int z=0; z < H; z++){
        for( int y=0; y < N; y++){
            for( int x=0; x < M; x++){
                cin >> map[z][y][x];
                if( map[z][y][x] == 1 ){
                    q.push({z,y,x}); 
                 }
             }
        }
    }
}
int main(){
    InputData();
    Solve();

    for( int z=0; z <H; z++){
        for( int y=0; y < N; y++){
            for( int x=0; x < M; x++){
                if( map[z][y][x] == 0 && path[z][y][x] == 0 ){
                    cout << -1 << endl;	
                    return 0;
                }
            }
        }
    }

    int ans = -1;
    for( int z=0; z < H; z++){
        for( int y=0; y < N; y++){
            for( int x=0; x < M; x++){
                if( path[z][y][x] > ans ){
                    ans = path[z][y][x];	
                }
            }
        }
    }
    cout << ans << endl;

    return 0;
}
/*baekjoon 7569 토마토 BFS*/
반응형
반응형

문제

방향 없는 그래프가 주어졌을 때, 연결 요소 (Connected Component)의 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주어진다.

출력

첫째 줄에 연결 요소의 개수를 출력한다.

 

예제 입력 1 
6 5
1 2
2 5
5 1
3 4
4 6
예제 출력 1 
2
예제 입력 2 
6 8
1 2
2 5
5 1
3 4
4 6
5 4
2 4
2 3
예제 출력 2 
1

 

/*[11724] baekjoon 연결 요소의 개수*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int) 1e3) 

int N,M,cnt=0;
int s[MAXN*MAXN], e[MAXN*MAXN];
int mat[MAXN+10][MAXN+10];
int visited[MAXN+10];

void InputData(){
	int u, v;
	cin >> N >> M;
	for (int i=0; i<M; i++){
		cin >> u >> v;
		mat[u][v] = 1;
		mat[v][u] = 1;
	}
}
void DFS(int x){
	visited[x] = 1;
	for(int i =1; i<=N; i++){
		if(mat[x][i] ==1 && visited[i] ==0){
			DFS(i);
		}
	}
}
void BFS(int x){
	int t;
	queue <int> q;
	q.push(x);
	visited[x] = 1;
	while( !q.empty()){
		t = q.front();
		q.pop();
		for(int i=1; i<=N; i++){
			if(mat[t][i] == 1 && visited[i] ==0){ 
				q.push(i);
				visited[i] =1;
			}
		}
	}
}
void Solve(){
	for(int i=1; i<=N; i++){
		if(visited[i] ==0){
			BFS(i);
			cnt++;
		}
	}
	cout << cnt << endl;
}
int main(){
	InputData();
	Solve();
	return 0;
}
/*[11724] baekjoon 연결 요소의 개수*/
반응형
반응형

문제

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는 안전한 영역이 최대로 몇 개가 만들어 지는 지를 조사하려고 한다. 이때, 문제를 간단하게 하기 위하여, 장마철에 내리는 비의 양에 따라 일정한 높이 이하의 모든 지점은 물에 잠긴다고 가정한다.

어떤 지역의 높이 정보는 행과 열의 크기가 각각 N인 2차원 배열 형태로 주어지며 배열의 각 원소는 해당 지점의 높이를 표시하는 자연수이다. 예를 들어, 다음은 N=5인 지역의 높이 정보이다.

 

이제 위와 같은 지역에 많은 비가 내려서 높이가 4 이하인 모든 지점이 물에 잠겼다고 하자. 이 경우에 물에 잠기는 지점을 회색으로 표시하면 다음과 같다. 

 

물에 잠기지 않는 안전한 영역이라 함은 물에 잠기지 않는 지점들이 위, 아래, 오른쪽 혹은 왼쪽으로 인접해 있으며 그 크기가 최대인 영역을 말한다. 위의 경우에서 물에 잠기지 않는 안전한 영역은 5개가 된다(꼭짓점으로만 붙어 있는 두 지점은 인접하지 않는다고 취급한다). 

또한 위와 같은 지역에서 높이가 6이하인 지점을 모두 잠기게 만드는 많은 비가 내리면 물에 잠기지 않는 안전한 영역은 아래 그림에서와 같이 네 개가 됨을 확인할 수 있다. 

이와 같이 장마철에 내리는 비의 양에 따라서 물에 잠기지 않는 안전한 영역의 개수는 다르게 된다. 위의 예와 같은 지역에서 내리는 비의 양에 따른 모든 경우를 다 조사해 보면 물에 잠기지 않는 안전한 영역의 개수 중에서 최대인 경우는 5임을 알 수 있다. 

어떤 지역의 높이 정보가 주어졌을 때, 장마철에 물에 잠기지 않는 안전한 영역의 최대 개수를 계산하는 프로그램을 작성하시오.

 

입력

첫째 줄에는 어떤 지역을 나타내는 2차원 배열의 행과 열의 개수를 나타내는 수 N이 입력된다. N은 2 이상 100 이하의 정수이다. 둘째 줄부터 N개의 각 줄에는 2차원 배열의 첫 번째 행부터 N번째 행까지 순서대로 한 행씩 높이 정보가 입력된다. 각 줄에는 각 행의 첫 번째 열부터 N번째 열까지 N개의 높이 정보를 나타내는 자연수가 빈 칸을 사이에 두고 입력된다. 높이는 1이상 100 이하의 정수이다.

 

출력

첫째 줄에 장마철에 물에 잠기지 않는 안전한 영역의 최대 개수를 출력한다.

 

예제 입력 1 
5
6 8 2 6 2
3 2 3 4 6
6 7 3 3 2
7 2 5 3 6
8 9 5 2 7

예제 출력 1 
5

예제 입력 2 
7
9 9 9 9 9 9 9
9 2 1 2 1 2 9
9 1 8 7 8 1 9
9 2 7 9 7 2 9
9 1 8 7 8 1 9
9 2 1 2 1 2 9
9 9 9 9 9 9 9

예제 출력 2 
6

예제 입력 3
5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

예제 출력 3 
1

예제 입력 4
5
3 3 3 3 3
3 3 3 3 3
3 3 3 3 3
3 3 3 3 3
3 3 3 3 3

예제 출력 4
1

 

문제 풀이

 

 

/*baekjoon 2468 안전 영역*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN ((int) 1e2) 

int N,cnt=0,maxval=0,minval=MAXN;
int Map[MAXN+10][MAXN+10];
int reMap[MAXN+10][MAXN+10];
int visited[MAXN+10][MAXN+10];

int dy[]={-1, 1, 0, 0};
int dx[]={0, 0, 1, -1};
int nx,ny;
bool inRange(int y, int x){
    return( (y>=1) && (y<=N) && (x >=1) && (x<=N));}

void DFS(int y, int x,int n){
    visited[y][x] = 1;

    for(int i=0; i<4; i++){
        ny=y+dy[i];
        nx=x+dx[i];
        if(Map[ny][nx] > n && visited[ny][nx] == 0){
            DFS(ny, nx, n);
        }
    }
}
void BFS(int y, int x){
    int ny, nx; 
    queue <pair<int, int>> q;
    q.push(pair<int,int>(y,x));

    while(!q.empty()){
        y = q.front().first;
        x = q.front().second;

        q.pop();
        for(int i=0; i<4; i++){
            ny = y + dy[i];
            nx = x + dx[i];
            if(inRange(ny, nx) && reMap[ny][nx]){
                q.push(pair<int,int>(ny,nx));
                reMap[ny][nx] =0; 
            }
        }
    }   
}
void remap(int num){
    for(int i=1; i<=N; i++){
        for(int j=1; j<=N; j++){
        if(Map[i][j] <= num){
            reMap[i][j] = 0;
        }else{
            reMap[i][j] = 1;
        }
        }
    }
}
void Solve(){
    int maxcnt=0;
    for(int k=0; k<100; k++){
    memset(visited, false, sizeof(visited));
    cnt=0;
    for(int i=1; i<=N; i++) {
        for(int j=1; j<=N; j++) {
            if(Map[i][j] > k && visited[i][j]==0 ){
                cnt++;
                DFS(i,j,k);
                //BFS(i,j);
            }
        }
    }
        if( cnt > maxcnt) maxcnt = cnt;
    }
    cout << maxcnt << endl;
}
void InputData(){
    cin >> N;
    for( int i=1; i<=N; i++){
        for( int j=1; j<=N; j++){
            cin >> Map[i][j];
            if(minval > Map[i][j] ) minval= Map[i][j];
            if(maxval < Map[i][j] ) maxval= Map[i][j];
        }
    }
}
int main(){
    InputData();
    Solve();
    return 0;
}
/*baekjoon 2468 안전 영역*/

 

반응형

+ Recent posts