#include <bits/stdc++.h>
using namespace std;
/*
함수2 - 형성평가6
자료의 개수 7을 매크로 상수로 정의하여 자료의 개수만큼 정수를 입력받아 입력받은
순서대로 앞에서부터 마지막까지 가면서 바로 뒤의 숫자와 비교하여 크면 교환한다.
이러한 작업을 세 번 반복한 후 그 결과를 하나의 행에 공백으로 구분하여 출력하는 프로그램을 작성하시오.
입력 예
15 20 41 8 26 33 19
출력 예
8 15 20 19 26 33 41
*/
#define CNT 7
void f(int a[])
{
int i,j;
for(i=1; i<=3; i++){
for(j=1; j<CNT; j++){
if(a[j]>a[j+1]){
swap(a[j],a[j+1]);
}
}
}
}
int main()
{
int i,a[1004];
for(i=1; i<=CNT; i++){
scanf("%d",&a[i]);
}
f(a);
for(i=1; i<=CNT; i++){
printf("%d ",a[i]);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*
함수2 - 형성평가5
세 개의 실수를 입력받아 합계와 평균을 구하여 평균을 반올림한 정수를 출력하고,
다음은 입력받은 수를 각각 먼저 반올림한 후 합계와 평균을 구하여 평균을 반올림한
한 결과를 출력하는 프로그램을 작성하시오.
입력 예
153.74 34.59 109.5
출력 예
99
100
*/
int f(float a,float b,float c)
{
float x;
x=(a+b+c)/3;
x=round(x);
return x;
}
int f2(float a,float b,float c)
{
float y;
y=(round(a)+round(b)+round(c))/3;
y=round;
return y;
}
int main()
{
int k,k2;
float a,b,c;
scanf("%f %f %f",&a,&b,&c);
k=f(a,b,c);
k2=f2(a,b,c);
printf("%d %d",k,k2);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*
함수2 - 형성평가4
정수 n을 입력받아 2n의 값을 출력하는 프로그램을 작성하시오. (1 ≤ n ≤ 20)
입력 예
10
출력 예
1024
*/
int power(int a)
{
int k=1,i;
for(i=1; i<=a; i++){
k=k*2;
}
return k;
}
int main()
{
int a,f;
scanf("%d",&a);
f=power(a);
printf("%d",f);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*
함수2 - 형성평가4
정수 n을 입력받아 2n의 값을 출력하는 프로그램을 작성하시오. (1 ≤ n ≤ 20)
입력 예
10
출력 예
1024
*/
int main()
{
int a,f;
scanf("%d",&a);
f=pow(2,a);
printf("%d",f);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
int n, k;
int in[10];
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> in[i];
}
int cnt = 0;
for (int i = n - 1; i >= 0; i--)
{
while (k / in[i])
{
cnt += k / in[i];
k = k % in[i];
}
}
printf("%d", cnt);
return 0;
}
N-Queen문제 생각보다 어렵죠? 아마도 N-Queen문제에서 막혀서 찾아오셨다면, 아마도 백트랙킹 / 재귀함수에 대해서 아주 조금 이해가 힘드셔서 오셨을것 같네요.^^ 아래 코드보시면서 도움 되시기 바랍니다.
각 행을 한개씩 내려가면서 Queen을 놓을 곳을 찾아가면 될것 같다.
첫번째 행의 어느 열에 Queen을 위치시키면, 그 열과 대각선 방향을 더이상 Queen을 놓을수 없음을 표시해야 한다.
bool check_right_up[100]; //이미 대각선 오른쪽 위로 queen이 있는지 확인 위 코드는 아래 그림을 보고 이해할 수 있길 바랍니다. 대각선의 각 cell의 행값 + 열값은 unique하다는 걸 이용해서,
그 unique한 값을 배열의 index로 사용해서, 그 대각선에 이미 Queen이 위치해 있음을 판단하면 됩니다.
bool check_right_down[100]; //이미 대각선 오른쪽 아래로 queen이 있는지 확인
아래 그림은 행-열을 한 값을 표시하고 있다. 음수가 발생하니, 모든 값들에 N을 더하면,
1,2,3,4,5,6,7 로 unique한 값을 만들수 있고, 이것을 배열의 index로 이용하면 됩니다.
#include <bits/stdc++.h>
using namespace std;
bool a[15][15];
int n;
bool check_col[15]; //이미 그 열에 queen이 있는지 확인
bool check_right_up[100]; //이미 대각선 오른쪽 위로 queen이 있는지 확인
bool check_right_down[100]; //이미 대각선 오른쪽 아래로 queen이 있는지 확인
void check_onoff(int row, int col, bool onoff)
{
check_right_up[row + col] = onoff;
check_right_down[row - col + n] = onoff;
check_col[col] = onoff;
a[row][col] = onoff;
}
bool check(int row, int col) {
// 같은 열 확인
if (check_col[col]) {
return false;
}
// 오른쪽 위방향 대각선 확인 (왼쪽 아래도^^)
if (check_right_up[row + col]) {
return false;
}
// 오른쪽 아래 방향 대각선 확인 (왼쪽 위도^^)
if (check_right_down[row - col + n]) {
return false;
}
return true;
}
int N_Queen(int row) {
if (row == n) {
return 1;
}
int cnt = 0;
for (int col = 0; col < n; col++) {
if (check(row, col)) { //이 row, col위치에 놓을수 있을지 확인
check_onoff(row, col, true); //놓을 수 있으니까, 그 위치 관련해서 놓았다는 표시를 함
cnt += N_Queen(row + 1); //다음 행에 queen을 놓으로 감.
check_onoff(row, col, false); //row, col 기준으로 확인해보 후 임으로, 다시 해제함.
}
}
return cnt;
}
int main() {
cin >> n;
cout << N_Queen(0) << '\n';
return 0;
}
이거 알아요? 블랙홀은 중력이 완전완전 쌔요. 그래서 누가 거기 안에 들어가면 거기 안에서 죽어요.그리고 밖으로 나갈 수도 없어요.
웜홀 중간에 블랙홀이 있어요. 만약에 어떤 생명체가 웜홀 안에 있는 블랙홀에 들어가면, 죽어서 블랙홀 밖으로 나와요. 그리고 다른 우주로 들어가요.
do you know that black holes have lots and lots of gravity.So if anything gets sucked in they would probly die and also they can never get out of the black hole.
chapter two: how to get out of a black hole. The only way to get out of a black hole is you have go in a black hole that is in a wormhole because remember wormholes has two sides so you first go in the black side of the worm hole and next you come out in the white side of the wormhole.So that is the end of my story so bye bye!
길이가 K인 수열 A가 A1≤ A2≤ ... ≤ AK-1≤ AK를 만족하면, 비내림차순이라고 한다.
따라서 N과 M (2)에서 재귀함수의 첫번째 인자만, i+1이 아니랑 i를 주면 된다.
즉, i값을 포함해서 다음 수를 정해나가는 형태이다. 왜냐? 중복을 허용하기 때문이다.
#include <bits/stdc++.h>
using namespace std;
vector <int> nm;
void NM4(int, int, int);
int main() {
int n, m;
cin >> n >> m;
NM4(1, n, m);
return 0;
}
void NM4(int s, int n, int m) {
if (nm.size() == m) {
for (int i = 0; i < m; i++) {
cout << nm[i] << " ";
}
cout << '\n';
return;
}
for (int i = s; i <= n; i++) {
nm.push_back(i);
NM4(i, n, m); //현재 nm vector에 넣은 수 이후 수를 확인 한다. (오름차순)
nm.pop_back();
}
}
내 생각에는 N과 M(1)보다 풀이에 접근하기 더 쉬운 문제라고 생각한다. 내기준으로는 "N과 M(0)" 이 맞을듯.^^
#include <bits/stdc++.h>
using namespace std;
vector <int> res;
void NM3(int n, int m) {
if (res.size() == m) {
for (int i = 0; i < m; i++) {
cout << res[i] << " ";
}
cout << '\n';
return;
}
for (int i = 1; i <= n; i++) {
res.push_back(i);
NM3(n, m);
res.pop_back();
}
}
int main() {
int n, m;
cin >> n >> m;
NM3(n, m);
return 0;
}
연결요소 문제와 유사하게 방문하지 않은 정점을 찾아서 dfs / bfs 순회를 해주면 된다.
여기서 정점의 정보는 [행,열]이 된다. 즉, (x,y)값을 한개의 정점으로 생각하면 됨.
그리고 이런 문제에서는 인접 정점을 찾는 방법은 아래와 같이 한개 정점 (x,y)에서 위/아래/좌/우로 이동을 위해 변경되야할 좌표값을 아래 배열과 같이 넣어두고 for문을 돌리면 간단하게 구현 할 수 있다.
int dx[] = { 0,0,1,-1 }; int dy[] = { 1,-1,0,0 };
연속된 숫자중 1개 자리씩만 입력을 받고 싶을경우 아래 코드를 이용하면 된다.
scanf("%1d", &input[i][j]);
아래 소스코드는 bfs를 사용해서 해결하였다.
#include <bits/stdc++.h>
using namespace std;
int input[30][30];
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
int n;
int res[25 * 25];
#define Dangi_Start_Num 2 //플러드 필에 사용되는 단지 시작 번호
void bfs(int x, int y, int cnt) {
queue<pair<int, int>> q;
q.push(make_pair(x, y));
input[x][y] = cnt;
while (!q.empty()) {
x = q.front().first;
y = q.front().second;
q.pop();
for (int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if (0 <= nx && nx < n && 0 <= ny && ny < n) { //input 배열의 범위밖을 참조하지 않도록 하기 위해
if (input[nx][ny] == 1) {
q.push(make_pair(nx, ny));
input[nx][ny] = cnt;
}
}
}
}
}
int main() {
//지도 정보 입력 받기
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%1d", &input[i][j]);
}
}
//플러드 필
int cnt = Dangi_Start_Num;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (input[i][j] == 1) {
bfs(i, j, cnt++);
}
}
}
//단지 개수 출력
printf("%d\n", cnt - Dangi_Start_Num);
//플러드 필된 값(즉, 단지번호) 별로 몇개가 있는지 개수를 셈
//그 개수를 res배열에 index는 단지배열이고, 그곳에 그 단지의 개수를 저장해둠.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (input[i][j] != 0)
res[input[i][j] - Dangi_Start_Num] += 1;
}
}
//res를 오른 차순으로 정렬함.
sort(res, res + cnt - Dangi_Start_Num);
//단지별 개수를 오름차순으로 출력함.
for (int i = 0; i < cnt - Dangi_Start_Num; i++) {
printf("%d\n", res[i]);
}
return 0;
}
연결 요소의 개수의 경우, DFS나 BFS를 공부를 공부한 후라면 간단하게 해결 가능하다.
모든 정점을 대상으로 방문한 적이 없는 정점이 있으면 그 정점을 기준으로 DFS 또는 BFS순회를 통해 방문했다는 체크를 해둔다. 그 후에도 아직 방문하지 않은 정점이 있다면 또 DFS나 BFS를 통해 순회하면서 방문했다는 체크를 하면 된다.
#include <bits/stdc++.h>
using namespace std;
int n, l;
vector <int> a[1005];
int visited[1005] = { 0, };
void dfs_l(int s) {
int i;
visited[s]++;
for (i = 0; i < a[s].size(); i++){
if (visited[a[s][i]] == 0){
dfs_l(a[s][i]);
}
}
}
int main()
{
int i, n1, n2, cnt = 0;
scanf("%d %d", &n, &l);
//간선 정보를 입력 받아 그래프 만들기
for (i = 0; i < l; i++){
scanf("%d %d", &n1, &n2);
a[n1].push_back(n2);
a[n2].push_back(n1);
}
//DFS 순회시에 인접 정점중에 정점번호가 작은 값부터 순회하기 위해 정렬
//이번 문제에서는 굳이 없어도 됨.
for (int i = 0; i < n; i++) {
sort(a[i].begin(), a[i].end());
}
//방문하지 않은 정점을 발견하면 DFS순회함.
//DFS가 호출되는 횟수가 연결요소의 개수가 됨.
for (int i = 1; i <= n; i++){
if (visited[i] == 0){
dfs_l(i);
cnt++;
}
}
printf("%d", cnt);
return 0;
}