블로그 이미지
shadowchaser
이곳 저곳 이것 저것

calendar

1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

Notice

2016. 8. 26. 01:34 Algorithm/BFS

정올 경로찾기

길이가 같은 두 개의 이진수 코드 A와 B가 있다고 하자. 이 두 코드 사이의 해밍 거리는 A와 B의 각 비트를 왼쪽부터 오른쪽으로 차례대로 비교할 때 서로 다른 값을 가진 비트의 수이다. 예를 들어, A=010010, B=011011 이라고 하면, 세 번째 비트와 여섯 번째 비트만 서로 다르므로 이 두 코드 사이의 해밍 거리는 2이다.

우리는 총 N개의 이진 코드를 가지고 있고, 각 코드의 길이는 K로 같다.

예를 들어, 다음과 같이 길이가 3인 5개의 이진 코드들이 있다.

A=000, B=111, C=010, D=110, E=001

두 코드 사이의 해밍 거리를 H(A,B)로 표현한다. 그러면, H(A,B)=3, H(A,C)=1, H(A,D)=2, H(A,E)=1 이다.

우리는 이진 코드들에 대해 해밍 경로를 찾고자 한다. 해밍 경로는 모든 인접한 두 코드사이의 해밍 거리가 1인 경로이다. 위의 예에서 (A,C,D)는 코드 A와 C의 해밍 거리가 1이고, 코드 C와 D의 해밍 거리가 1이므로 해밍 경로이다. (A,E,B)는 코드 A와 E의 해밍 거리는 1이지만, 코드 E와 B의 해밍 거리가 2이므로 해밍 경로가 아니다.

이 문제는 주어진 두 코드 사이에 가장 짧은 해밍 경로를 구하는 프로그램을 작성하는 것이다. 


입력 /*

5 3

100

111

010

110

001

1 2

*/


나중에 재귀적으로 돌리기만 하면 됨.

#include <stdio.h>


int SERO;

int GARO;

int map[1010][32];

int tmp[32];

int check[32]; //가본곳

int START;

int END;

typedef struct {

int path[32];

int pastposition;

int step;

int idx;

}_pos;

_pos POSITION[10000];

int main(void)

{

// 여기서부터 작성

scanf("%d", &SERO);

scanf("%d", &GARO);

int i, j,k;

for (i = 0; i < SERO; i++)

{

for (j = 0; j < GARO; j++)

{

scanf("%1d", &map[i][j]);

}

}

scanf("%d", &START);

START--;

scanf("%d", &END);

END--;


int head = 0, tail = 1;

check[START] = 1;

for (i = 0; i < GARO; i++)

{

POSITION[0].path[i] = map[START][i];

}

while (1)

{

if (head == tail) break;

for (int dir = 0; dir < GARO; dir++)

{

// 하나씩 bit 를 바꿔봄

for (i = 0; i < GARO; i++)

{

tmp[i] = map[head][i];

}

tmp[dir] = !tmp[dir];

// 동일한게 있는지 search한다

int match = 1; // 0이 맞는게 없다는 뜻 1이 다 맞다는 거

for (i = 0; i < SERO; i++)

{

match = 1;

for (j = 0; j < GARO; j++)

{

if (tmp[j] != map[i][j])

{

match = 0; 

}

}

if (match == 1 && i == END)// GOAL이 있다면 아웃

{

for (k = 0; k < GARO; k++)

{

POSITION[tail].path[k] = tmp[k];

}

POSITION[tail].pastposition = head;

POSITION[tail].step = POSITION[head].step + 1;

POSITION[tail].idx = i;

check[i] = 1;

printf("found!!");

goto out;

}

if (match == 1 && !check[i]) // 끝은 아니지만 연결은 되었다면 

{

//queue에 넣어라

for (k = 0; k < GARO; k++)

{

POSITION[tail].path[k] = tmp[k];

}

POSITION[tail].pastposition = head;

POSITION[tail].step = POSITION[head].step + 1;

POSITION[tail].idx = i;

check[i]= 1;

tail++;

}

}

}

head++;

}

out:

printf("Aaa");

// 맨 마지막에 위치를 역으로 찾아가게만 하면 된다.




return 0;

}

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

정올 등산로 찾기  (0) 2016.06.17
정올 저글링 방사능 오염  (0) 2016.06.15
정올 보물섬  (0) 2016.05.21
정올 장기  (0) 2016.05.09
정올 치즈 BFS  (0) 2016.04.04
posted by shadowchaser
2016. 8. 25. 00:19 Algorithm/DFS

#include <stdio.h>

/*

첫 줄에 노드 수 N(1≤N≤12)와 색상 번호 M(1≤M≤12)가 주어진다.

출력

노드1부터의 칠해진 색상 번호 리스트를 출력한다.

불가능한 경우 -1을 출력한다.

입력 예시

4 3

0

1 0

1 1 0

0 1 1 0

출력 예시

1 2 3 1

*/

 

// 그래프칠하기
#include <stdio.h>
/*
4 3
0
1 0
1 1 0
0 1 1 0
*/
int N;//노드수
int M;//색상번호
int SOL[14];
int MAP[14][14];
int RET;

int check( int V, int color) // V : 위치 , V : 색상
{
 int i;
 for (i = 1; i <= N; i++)
 {
  if (MAP[V][i] && SOL[i] == color) return 1; //인접한 정점에 같은 색이 이미 칠해져있는지 점검한다.
 }
 return 0;
}
int flag;
int dfs(int V)  // V: 접점
{
 if (V > N) {
  return 1;
 }
 int j;
 for (j = 1; j <= M; j++)
 {
  if (check(V, j) == 1) continue;
  SOL[V] = j;
  if (dfs(V + 1) == 1) return 1;
  SOL[V] = 0;
 }
 return 0;
}
int main(void)
{
 scanf("%d %d", &N, &M);
 int i, j , tmp;
 for (i = 1; i <= N; i++)
 {
  for (j = 1; j <= i; j++)
  {
   scanf("%d", &tmp);
   MAP[i][j] = MAP[j][i] = tmp;
  }
 }

 RET = dfs(1);
 if (RET)
 {
  for (i = 1; i <= N; i++)
  {
   printf("%d ", SOL[i]);
  }

 }
 else
 {
  printf("-1");
 }
 return 0;

}


한편  이 문제는 "좋은 수열" 문제와도 굉장히 유사하다.

#include <stdio.h>
  
int N;
char a[80+10];
  
int flag;
  
int strncmp(const char *s1, const char *s2, unsigned int n)
{
      while(n--)
      {
            if(*s1 > *s2) return 1;
            else if(*s1 < *s2) return -1;
            else if(*s1 == 0) return 0;
            s1++;
            s2++;
      }
      return 0;
}
  
int Check(int s)
{
      int i, cnt;
  
      if(s == 0) return 1;
      else
      {
            cnt = ++s / 2;
            for(i=1 ; i<=cnt ; i++)
            {
                  if(strncmp(&a[s-i], &a[s-i*2], i) == 0) return 0;
            }
      }
      return 1;
}
  
void DFS(int s)
{
      char i;
      if(s >= N)
      {
            flag = 1;
      }

      for(i='1' ; i<='3' ; i++)
      {
            a[s] = i; // 여기가 다르다.!! 그래프 칠하기의 경우 색상을 넣을지 말지를 확인하고 넣었으나, 여기에선 일단 넣고 될때 까지 돌린다.
            if(Check(s) == 0) continue;
            DFS(s+1);
            if(flag==1) return;
      }
}
  
int main(void)
{
      
      scanf("%d",&N);
      DFS(0);
      printf("%s", a);
  
      return 0;
}


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

같은 모양 찾기  (0) 2016.06.27
DFS 정복!! 레벨 별  (0) 2016.06.22
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
단지번호 붙이기 - 정올 1695번  (2) 2016.02.25
posted by shadowchaser
2016. 8. 20. 08:18 Algorithm

/*

4 3 3

1 1

3 3

4 1

*/

#include <stdio.h>

#define ABS(t) ((t)<0?-(t):(t))

#define MAX(a,b) ((a)>(b)?(a):(b))

int W, H, N;//가로, 세로크기, 데이타개수

int x[1010], y[1010];

int min;

int main(void)

{

int i;

//freopen("input.txt", "r", stdin);

scanf("%d %d %d", &W, &H, &N);

for (i = 0; i < N; i++) {

scanf("%d %d", &x[i], &y[i]);

}

int cnt = 0, sx, sy, xdis, ydis;

sx = x[0], sy = y[0];

for (i = 1; i < N; i++) {

xdis = sx - x[i];

ydis = sy - y[i];

if (xdis * ydis >= 0) cnt += MAX(ABS(xdis), ABS(ydis));

else cnt += ABS(xdis) + ABS(ydis);

sx = x[i], sy = y[i];

}

printf("%d", cnt);


return 0;

}//

'Algorithm' 카테고리의 다른 글

바이너리서치를 통한 정올 예산  (0) 2016.08.20
에라토스테네스의 체 (소수 구하기)  (0) 2016.06.23
posted by shadowchaser
2016. 8. 20. 08:14 Algorithm


/*

국가의 역할 중 하나는 여러 지방의 예산요청을 심사하여 국가의 예산을 분배하는 것이다. 국가예산의 총액은 미리 정해져 있어서 모든 예산요청을 배정해 주기는 어려울 수도 있다. 그래서 정해진 총액 이하에서 가능한 한 최대의 총 예산을 다음과 같은 방법으로 배정한다.
 
(1) 모든 요청이 배정될 수 있는 경우에는 요청한 금액을 그대로 배정한다.
(2) 모든 요청이 배정될 수 없는 경우에는 특정한 정수 상한액을 계산하여 그 이상인 예산요청에는 모두 상한액을 배정한다. 상한액 이하의 예산요청에 대해서는 요청한 금액을 그대로 배정한다.
 
예를 들어, 전체 국가예산이 485이고 4개 지방의 예산요청이 각각 120, 110, 140, 150이라고 하자. 이 경우, 상한액을 127로 잡으면, 위의 요청들에 대해서 각각 120, 110, 127, 127을 배정하고 그 합이 484로 가능한 최대가 된다.
 
여러 지방의 예산요청과 국가예산의 총액이 주어졌을 때, 위의 조건을 모두 만족하도록 예산을 배정하는 프로그램을 작성하시오.


예제)

입력 예시

4

120 110 140 150

485

출력 예시

127

입력 예시

5

70 80 30 40 100

450

출력 예시 

100

*/


#include<stdio.h>

int N, M;

int a[10000 + 10];

int check(int m) {

int i, sum = 0;

for (i = 0; i < N; i++)

{

sum += MIN(a[i], m);

}

if (sum <= M)    return 1;

return 0;

}

int main(void) {

int i, sol, s, e, m, sum = 0, max = 0;

scanf("%d", &N);

for (i = 0; i < N; i++) {

scanf("%d", &a[i]);

sum += a[i];

if (a[i]>max) max = a[i];

}

scanf("%d", &M);

if (sum <= M) printf("%d", max);

else {

s = 0;

e = max;

while (s <= e) {

m = (s + e) / 2;

if (check(m) == 1) {

sol = m;

s = m + 1;

}

else e = m - 1;

}

printf("%d", sol);

}


return 0;


}

'Algorithm' 카테고리의 다른 글

절대값 MAX 매크로  (0) 2016.08.20
에라토스테네스의 체 (소수 구하기)  (0) 2016.06.23
posted by shadowchaser
2016. 8. 6. 00:07 Algorithm/기본 이론


'Algorithm > 기본 이론' 카테고리의 다른 글

정올 지하철  (0) 2016.07.23
공부 순서  (0) 2016.06.13
bubble sort  (0) 2016.03.12
default  (0) 2016.02.27
posted by shadowchaser
2016. 7. 23. 01:24 Algorithm/기본 이론
floyd warshall인가.. 이게 중요함. 느려도 이거 쓰면 편하게 구할 수 있음.


#include<stdio.h>
 
int s[110][110], p[110][110], n, m;
void path(int s, int e)
{
    if (p[s][e] == 0)  return;
    path(s, p[s][e]);
    printf("%d ", p[s][e]);
    path(p[s][e], e);
}
 
int main()
{
 
    /*
    5 5
    0 2 2 5 9
    2 0 3 4 8
    2 3 0 7 6
    5 4 7 0 5
    9 5 6 5 0
    */
    int i, j, k;
    scanf("%d %d", &n, &m);
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++) {
            scanf("%d", &s[i][j]);
        }
    }  
 
    for (k = 1; k <= n; k++) {
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= n; j++) {
                if (s[i][j] > s[i][k] + s[k][j]) {
                    s[i][j] = s[i][k] + s[k][j];
                    p[i][j] = k;
                }
            }
        }
    }
    printf("%d\n", s[1][m]);
    printf("1 ");
    path(1, m);
    printf("%d ", m);
    return 0;
}


'Algorithm > 기본 이론' 카테고리의 다른 글

순열, 중복순열, 조합, 중복조합  (0) 2016.08.06
공부 순서  (0) 2016.06.13
bubble sort  (0) 2016.03.12
default  (0) 2016.02.27
posted by shadowchaser
2016. 6. 27. 23:41 Algorithm/DFS

#include <stdio.h>



int BIG;

int BIGMAP[110][110];

int SMALL;

int SMALLMAP[110][110];

int main(void)

{

freopen("1.txt", "r", stdin);

// 여기서부터 작성

scanf("%d", &BIG);

for (int i = 1; i <= BIG; i++)

for (int j = 1; j <= BIG; j++)

scanf("%1d", &BIGMAP[i][j]);

int count = 0;

scanf("%d", &SMALL);

for (int i = 0; i < SMALL; i++)

for (int j = 0; j < SMALL; j++)

scanf("%1d", &SMALLMAP[i][j]);

int dir;

int tmpcnt = 0;

for (int i = 1; i <= BIG - SMALL + 1; i++) {

for (int j = 1; j <= BIG - SMALL + 1; j++) {

for ( dir = 0; dir < 4; dir++)

{

for (int i = 0; i<SMALL / 2; i++) {

for (int j = i; j<SMALL - i - 1; j++) {

int tmp = SMALLMAP[i][j];

SMALLMAP[i][j] = SMALLMAP[j][SMALL - i - 1];

SMALLMAP[j][SMALL - i - 1] = SMALLMAP[SMALL - i - 1][SMALL - j - 1];

SMALLMAP[SMALL - i - 1][SMALL - j - 1] = SMALLMAP[SMALL - j - 1][i];

SMALLMAP[SMALL - j - 1][i] = tmp;

}

}

if (BIGMAP[i][j] == SMALLMAP[0][0])

{

int check = 1;

for (int x = 0; x < SMALL; x++) {

for (int y = 0; y < SMALL; y++) {

if (BIGMAP[i + x][j + y] != SMALLMAP[x][y])

{

//printf("==>[NOT MATCHED!] [dir:%d] i: %d j: %d -> x: %d, y: %d\n", dir, i, j, x, y);

check = 0;

}

else {

tmpcnt++;

//printf("==>[%d MATCHED, cnt:%d][dir:%d] i: %d j: %d -> x: %d, y: %d\n", tmpcnt, count, dir, i, j, x, y);

}

if (check == 0) {

break;

}

}

}

tmpcnt = 0;

if (check == 1)

count++;

}

}

}

}

printf("%d", count);

return 0;

}

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

정올 그래프 칠하기, 좋은 수열  (0) 2016.08.25
DFS 정복!! 레벨 별  (0) 2016.06.22
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
단지번호 붙이기 - 정올 1695번  (2) 2016.02.25
posted by shadowchaser
2016. 6. 25. 00:47 Algorithm/Backtracking

기본적으로 풀기 어려우면 무조건 부분집합 돌려서 각 값을 대입해서 최대 최소값 구하고 본다. 그러면 중간이라도 간다.

#include <stdio.h>

int data[]={1,2,3,4};
int flag[]={0,0,0,0};

void powerset(int n,int depth)
{
    if(n==depth){
        int i;
        printf("{");
        for(i=0;i<n;i++){
            if(flag[i]==1)printf("%d ",data[i]);
        }
        printf("}\n");
        return;
    }
    flag[depth]=1;
    powerset(n,depth+1);
    flag[depth]=0;
    powerset(n,depth+1);
}

int main()
{
    powerset(sizeof(data)/sizeof(int),0);
    return 0;    
}



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

정올 해밀턴 순환 회로  (0) 2016.06.22
정올 영역구하기  (0) 2016.06.13
posted by shadowchaser
2016. 6. 23. 00:23 Algorithm

소수를 구하는 방법중엔 에라토스테네스의 체 방법이 꽤 효과적이다.

어차피 알고리즘 문제에서도 에라토스테네스의 체 를 응용한 문제가 더 많이 나올 테니 이것을 응용하는게 더 좋음.(TC가 많아도 일단 한번 다 저장하면 장땡이기 때문)

#include<stdio.h>


int N;

int arr[10001];

void prime(int num)

{

for (int i = 0; i < num; i++)

{

arr[i] = i;

}

for (int i = 2; i <= num; i++)

{

if (arr[i] == 0) continue; // 이미 체크된 수의 배수는 skip (이거 지우면 엄청 오래걸림)

for (int j = 2; j <= num; j++)

{

if (arr[j] != i && arr[j] % i == 0){

arr[j] = 0;

}

}

}

}

void main()

{

scanf("%d", &N);

prime(N);

}


그! 런! 데!!!이 방법이 더 좋다. 무조건 이 아래방법을 써야한다.!!!

예를 들어 10000까지의 소수를 구하려한다면, 아래 공식으로 써야한다. 100이라고 쓴 거 잘못쓴거 아님!

for (int i = 2; i < 100; i++)

{

if (prime[i] == 0) {

for (int j = i*i; j < 10000; j++)

{

prime[j] = 1;

}

}

}

}

'Algorithm' 카테고리의 다른 글

절대값 MAX 매크로  (0) 2016.08.20
바이너리서치를 통한 정올 예산  (0) 2016.08.20
posted by shadowchaser
2016. 6. 22. 03:39 Algorithm/DFS

이진 트리와 멀티 트리를 생각하면서 해보고,

관리해야할 항이 몇개인지 관리해보면 된다.

 

LV 1 예산관리

row도 필요없고, 걍 순서에서 값만 비교해보면 됨

#include <stdio.h>

int B/*예산*/, n/*개수*/, act[23], res;

void f(int i, int sum)  // i번활동, i-1까지의 합계

{

if (i == n + 1)

{

if (sum <= B && sum>res) //예산 보다는 작고 현재 값보다는 크면.

res = sum;

return;

}

f(i + 1, sum + act[i]); // i번째 활동을 포함하거나

f(i + 1, sum);         // 포함하지 않 거나

}

int main() {

int i;

scanf("%d %d", &B, &n);

for (i = 1; i <= n; i++)

scanf("%d", &act[i]);

f(1, 0);

printf("%d", res);

return 0;

}


LV 2 연구활동 가는길

flag를 두어 방문했던 곳을 한번만 가게 함

#include<stdio.h>

int n, m, G[11][11], sol = 0x7fffffff, chk[11];

void solve(int V, int W)

{

if (V == n)

{

if (W<sol) sol = W;

return;

}

for (int i = 1; i <= n; i++)

if (!chk[i] && G[V][i])

{

chk[i] = 1;

solve(i, W + G[V][i]);

chk[i] = 0;

}

}

int main(void)

{

scanf("%d %d", &n, &m);

for (int i = 0; i<m; i++)

{

int s, e, w;

scanf("%d %d %d", &s, &e, &w);

G[s][e] = G[e][s] = w;

}

solve(1, 0);

printf("%d\n", sol == 0x7fffffff ? ‐1 : sol);

return 0;

}


LV 3 해밀턴 순환 회로

flag를 두고, row도 두어 처리 함

#include<stdio.h>

int N;

int map[110][110];

int sol = 0x7fffffff;

int max = 0x7fffffff;

int chk[13];

void dfs(int V, int r,int cost)

{

if (cost >= sol) return;//만약 현재값이 ??

if (V >= N)

{

if (map[r][1] == 0) { 

return; 

}

cost += map[r][1];//비용 증가

if (cost < sol) sol = cost;

return;

}

for (int i = 2; i <= N; i++)

{

if (r == i) continue;

if (!chk[i] && map[r][i])//들러보지 않은 곳

{

chk[i] = 1;

dfs(V + 1, i, cost + map[r][i]);

chk[i] = 0;

}

}

}

void main()

{

freopen("input.txt", "r", stdin);

scanf("%d", &N);


for (int i = 1; i <= N; i++)

for (int j = 1; j <= N; j++)

{

scanf("%d", &map[i][j]);

}

dfs(1, 1, 0);

printf("%d", sol != max ? sol : 0);

}



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

정올 그래프 칠하기, 좋은 수열  (0) 2016.08.25
같은 모양 찾기  (0) 2016.06.27
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
단지번호 붙이기 - 정올 1695번  (2) 2016.02.25
posted by shadowchaser
prev 1 2 3 next