C++


#include<iostream>

#include<time.h>

#include "sort.h"

using namespace std;


const int N = 100000;

void MergeSort(int arr[], int l, int r, int divide)

{

int *first_Arr = new int[N + 1];

//int first_Arr[N + 1];

int first_Cnt = 0;

int *second_Arr = new int[N + 1];

//int second_Arr[N + 1];

int second_Cnt = 0;

for (int i = l; i <= divide; i++)

first_Arr[++first_Cnt] = arr[i];


for (int i = divide + 1; i <= r; i++)

second_Arr[++second_Cnt] = arr[i];


int first_index = 1;

int second_index = 1;

int present_Position = 0;

for (int i = l; i < l + (first_Cnt + second_Cnt); i++)

{

arr[i] = first_Arr[first_index] > second_Arr[second_index] ? second_Arr[second_index++] : first_Arr[first_index++];


if (first_index == first_Cnt + 1) // 첫번째 배열이 다 들어가서 두번째 배열만 넣어주면 되는 경우

{

for (int j = i + 1; j < l + (first_Cnt + second_Cnt); j++)

arr[j] = second_Arr[second_index++];

break;

}

else if (second_index == second_Cnt + 1) // 두번째 배열이 다 들어가서 첫번째 배열만 넣어주면 되는 경우

{

for (int j = i + 1; j < l + (first_Cnt + second_Cnt); j++)

arr[j] = first_Arr[first_index++];

break;

}

}


delete[] first_Arr;

delete[] second_Arr;

first_Arr = NULL;

second_Arr = NULL;

}


void NaturalMergeSort(int arr[], int l, int r)

{

int check_Cnt = 0; // 2개 일때 합병

int first_Merge_start = 1;

int check_Point;

int sw = 0;

for (int i = l + 1; i <= r; i++)

{

if (arr[i - 1] > arr[i])

{

check_Cnt++;

sw = 1;

if (check_Cnt == 1)

check_Point = i - 1;

}


if (check_Cnt == 2)

{

MergeSort(arr, first_Merge_start, i - 1, check_Point);

check_Cnt = 0;

first_Merge_start = i;

}


if (i == r && check_Cnt == 1)

MergeSort(arr, first_Merge_start, i, check_Point);


}

if (sw == 1)

NaturalMergeSort(arr, 1, N);

}


int main()

{

srand(time(NULL));

int *arr = new int[N + 1];

double start_time;

int rever = N;

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

arr[i] = rever--;

start_time = clock();

NaturalMergeSort(arr, 1, N);

cout << "총 걸린 시간 = " << (clock() - start_time)/CLOCKS_PER_SEC << "초" << endl;

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

// cout << arr[i] << " ";


CheckSort(arr, N);

delete[] arr;

arr = NULL;

return 0;

}


ADL


Natural_Merge_Sort(arr[], l, r)

     Arr_Cnt ← 1;

     run[Arr_Cnt][0] ← 1;

     for(i = l; i < r; i++) do {

         if(arr[i] > arr[i+1]) then {

             run[Arr_Cnt][1] = i;

             Arr_Cnt ← Arr_Cnt + 1;

             run[Arr_Cnt][0] = i + 1;

             }

     run[Arr_Cnt][1] = r;

     while(Arr_Cnt > 1) do {

         check ← 1;

             for (i = 1; i <= Arr_Cnt – 1; i ← i + 2) do {

                 MergeSort(Arr,run[i][0], run[i+1][1], run[i][1]);

                 run[check][0] = run[i][0];

                 run[check][1] = run[i + 1][1];

                 check++;

                 }

             run[check][0] = run[Arr_Cnt][0];

             run[check][0] = run[Arr_Cnt][1];

             Arr_Cnt ← Arr_Cnt - (check – 1 );

             }

end Natural_Merge_Sort(arr[], l, r, divide)


MergeSort(arr[], l, r, divide)

     for(i = divide + 1; i > l; i ← i – 1) do {

         merge_Arr[i-1] = arr[i-1];

         }

     for(j = divide;j < r; j ← j + 1) do {

         merge_Arr[r + divide – j] = arr[j + 1];

end MergeSort(arr[], l, r, divide)

목차 

◆ 알고리즘이란

◆ ADL

▶ 지정문

▶ 조건문

▶ 반복문

▶ 함수문

▶ 입출력문

◆ 순환

◆ 점근식 표기법

◆ 순환 알고리즘과 점화식


-------------------------------------------------------------------------------------------------------------------------


◆ 알고리즘(algorithm)

     ▶ 특정문제를 해결하기 위해 기술한 일련의 명령문

◆ 프로그램(program)

     ▶ 알고리즘을 컴퓨터가 이해하고 실행할 수 있는 특정 프로그래밍 언어로 표현한 것

◆ 알고리즘의 요건

     ▶ 완전성과 명확성

 * 수행결과와 순서가 완전하고 명확하게 명세되어야 함

 * 순수하게 알고리즘이 지시하는대로 실행하기만 하면 의도한 결과가 얻어져야 함

     ▶ 입력과 출력

 * 입력 : 알고리즘이 처리대야 할 대상으로 제공되는 데이타

 * 출력 : 입력 데이터를 처리하여 얻은 결과

     ▶ 유한성

 * 유한한  단계 뒤에는 반드시 종료


◆ ADL (Algorithm Description Language)

    ▶ 알고리즘 기술을 위해 정의한 언어

    ▶ 사람이 이해하기 쉽고, 프로그래밍 언어로의 변환이 용이 ( 여러가지 방식으로 기술할 수 있는거 있다 )

    ▶ 의사 코드 (pseudo-code) : ADL과 약간의 자연어로 기술한 것



    ▶ ADL 알고리즘에서 프로그램으로의 변환




   ▶ ADL 데이터 : 숫자, 부울(Boolean) 값 , 문자

   ▶ ADL의 명령문 :

* 종류 : 지정문 , 조건문 , 반복문 , 함수문 , 입력문 , 출력문

* 명령문 끝에는 세미콜론(;)을 사용


(알고리즘이란 끝)

-------------------------------------------------------------------------------------------------------------------------


◆ 지정문

▶ 형식 : 변수 ← 식;


▶ 식 ( expression )

*산술식

*부울식

- 결과 : 참 ( true ) 또는 거짓 ( false )

- 표현

》 논리 연산자 (and , or , not)

》 관계 연산자 (< , ≤ , = , ≠ , ≥ , >)

* 문자식


▶ 제어 구조 : 순차적

◆ 조건문

▶ 제어 구조 : 선택적

▶ 종류 : if문과 case문


◆ if문

▶ if (cond) then S1

   else S2 


◆ case문

▶ case {

cond1 : S1

cond2: S2

· · ·

condn : Sn

else : Sn+1

}



◆ 반복문

▶ 제어 구조 : 일정한 명령문 그룹을 반복해서 수행하는 루프(loop) 형태

▶ 종류 : while문 , for문 , do-while문


◆ while문

 ▶형식

* while (cond) do {

S1

}


 ▶무한 루프

* while (true) do {

S1

}


◆  for문

▶ 형식

* for (initialization; cond; increment) do

S

▶ 동등한 while문

* initialization

    while (cond) do {

S

increment;

}

▶ 무한 루프

* for ( ; ; ) do

S

( cond의 기정값이 true이므로)


◆ do - while문

▶ 형식

* do {

S

 }while( cond );

▶ while문 과의 차이점은 최소한 한 번은 실행 된다는 것이다.


◆ 루프 명령문

▶ goto 명령문 : 루프에서 바로 빠져나갈 때 사용 (의도치 않는 오류가 발생할 확률이 높아 거의 안쓴다고 알고있음)

▶ exit문 : 자신을 둘러싸고 있는 가장 가까운 루프 밖의 명령문으로 제어를 이동시킴 (c언어의 break; 역할)


◆ 함수문

▶ 형식

* function-name(parameter_list) 

S

end funcion_name()

▶ 호출 함수로의 복귀

* return expr;

* 여기서 expr은 함수의 실행 결과

▶ 함수 호출

* function-name(argument_list)

* 인자 리스트(argument_list)는 타입과 수에 있어서 함수의 형식 매개 변수와 대응되어야 함


▶ 인자와 매개변수와의 연관

* 값 호출 (call by value) 규칙

* 각 인자의 실제 값이 호출된 함수로 전달

* 인자의 값이 주소(참조)가 되면 매개 변수에 주소 값이 전달되어 값은 데이터 지시


◆  입력 함수

▶  read (argument_list);


◆ 출력 함수

▶ print (argument_list);


◆ 인자

▶ 변수나 인용 부호가 있는 문자열


◆ 기타 명령문

▶ stop : 현재 진행 중인 함수의 실행을 정지

▶ 코멘트 : //는 그 행 끝까지 , /* 과 */은 코멘트의 시작과 끝 표시

▶ 다차원 배열 : a[n1,n2, ˙˙˙, nn]


◆ ADL 기술 규칙

▶ 함수의 입·출력 변수를 명확히 명세

▶ 변수의 의미를 알 수 있게 정의

▶ 알고리즘의 제어 흐름은 되도록 순차적

▶ 시각적 구분을 위해 들여쓰기 이용

▶ 코멘트는 짧으면서 의미는 명확히

▶ 함수를 적절히 사용


(ADL 끝)

-------------------------------------------------------------------------------------------------------------------------



◆ 알고리즘의 평가 기준

▶ 원하는 결과의 생성 여부

▶ 시스템 명세에 따른 올바른 실행 여부

▶ 프로그램의 성능

▶ 사용법과 작동법에 대한 설명 여부

▶ 유지 보수의 용이성

▶ 프로그램의 판독 용이


◆ 알고리즘의 성능 평가

▶ 성능 분석 (performance analysis)

*  프로그램을 실행하는데 필요한 시간과 공간의 추정

▶ 성능 측정 (performance measurement)

* 컴퓨터가 실제로 프로그램을 실행하는데 걸리는 시간 측정



◆ 공간 복잡도 (space complexity)

▶ 알고리즘을 실행시켜 완료하는데 필요한 총 저장 공간

▶ Sa =Sc + Se

* S: 고정 공간

- 명령어 공간, 단순 변수 , 복합 데이타 구조와 변수 , 상수

* S: 가변 공간

- 크기가 변하는 데이터 구조와 변수들이 필요로 하는 저장 공간

- 런타임 스택 (runtime stack)을 위한 저장 공간


◆ 시간 복잡도 (time complexity)

▶ 알고리즘을 실행시켜 완료하는데 걸리는 시간

▶ T=Tc + Te

* Tc  : 컴파일 시간

 Te  : 실행 시간

- 단위 명령문 하나를 실행하는데 걸리는 시간

- 실행 빈도수 (frequency count)     (c , c++ 기준 for문 1억번 실행시 1초 , Java는 for문 5천만번 실행시 1초)


◆ 점근식 표기법 (Asymptotic notation)

▶ Big-Oh (O)

▶ Big-Omega (Ω)

▶ Big-Theta (Θ)







C++


#include <iostream>

#include <time.h>

using namespace std;

const int TRUE = 1;

const int FALSE = 0;


inline void swap(int a[] , int x1 , int x2){

    int temp = a[x1] ; a[x1] = a[x2] ; a[x2] = temp;

}


int N = 50000;                                  // 데이터 갯수


void Shaker_Sort(int *arr)

{

    int shift = 0 , sort = TRUE;

    int left = N, right = 1;                    // 왼 / 오

    

    while(TRUE)

    {

        for(int i = right; i<left;i++)          // Bubble 정렬 정방향

        {

            if(arr[i] > arr[i+1])

            {

                swap(arr, i, i+1);

                sort = FALSE;

            }

        }

        --left;

        if(sort == TRUE) return;                // 정렬이 한번도 안일어났다면 바로 종료

        sort = TRUE;

    

        for(int i = left; i > right;i--)        // Bubble 정렬 역방향

        {

            if(arr[i] < arr[i-1])

            {

                swap(arr,i , i-1);

                sort = FALSE;

            }

        }

        ++right;

        if(sort == TRUE) return;

        sort = TRUE;

    }

}


int main()

{

    int arr[N];

    double start_time;

    srand(time(NULL));

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

        arr[i] = rand() % 10001;

    start_time = clock();                   // 정렬하기전 시작시간 저장

    Shaker_Sort(arr);

    cout << "칵테일 쉐이커 정렬 실행 시간 = " << (clock()-start_time)/(CLOCKS_PER_SEC) << "초" <<endl;     // 정렬이 끝난 후 시간 - 정렬하기전 시작시간을 빼서 걸린시간 측정

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

    //    cout << arr[i] << " ";

    return 0;

}


ADL 

칵테일 쉐이크 정렬 – ADL
Shaker_Sort(arr[], N)
Sort  ← 1;// 1 = TRUE , 0 = FALSE
left  ← N;// N = 데이터 개수
right ← 1;
while(right > left) do {
for (i ← right; I < left; i ← i+1) do {
if (arr[i] > arr[i+1]) then {
temp ← arr[i];
arr[i] ← arr[i+1];
arr[i+1] ← temp;
}
}
left ← left – 1;
for (i ← left; i > right; i ← i-1) do {
if (arr[i] < arr[i-1]) then {
temp ← arr[i];
arr[i] ← arr[i-1];
arr[i-1] ← temp;
}
}
right ← right + 1;
}
end Shaker_Sort(arr[], N)

칵테일 정렬의 성능은 최상의 경우 O(n) , 최악의 경우 O(n^2)

초록색선 : 유클리드 거리 측정법 = 두 점을 잇는 가장 짧은 거리의 길이 (도로 사정 X)


예를 들어 우리집 (A)  과 역 (B) 이 있을때 도로 사정 생각하지않고 모든걸 가로 질러 가장 가까운 거리를 나타내는것

위에 사진을 보면 초록색선을 생각하면 된다.


퍼렁선 : 맨하탄 거리 측정법 = 두 점을 잇는 가장 짧은 거리의 길이 (도로 사정 O)


위에 예와 똑같다고 생각할때 옵션이 하나 더 추가된다고 생각하면 된다. 도로를 생각하며 가장 짧은 거리로 가야한다.

퍼렁선을 보면 가운데로 가로 질러 가지 못하고 길을 따라 최단거리 이동을 하고 있다.


여기서 잘보면 퍼렁선과 빨간색은 길이가 똑같다.


그래서 맨하탄 거리 측정법의 공식은 

두좌표 (X1,Y1)  , (X2,Y2) 가 있을때   X 좌표의 차의 절대값 + Y좌표의 차의 절대값  ==>  |(X2-X1)| + |(Y2-Y1)|  음청 간단하다.



위에 문제의 조건에서 초밥의 가짓수 d를 억 단위로 조건을 줄경우 어떻게 풀어야 할까?

  2<= d <= 3000 일때는 인덱스에다 그냥 떄려 박아서 풀었다. 

하지만 억단위로 넘어갈 경우 인덱스를 쓸수 없다.

그래서 직접만든 sort함수로 같은 종류의 반복되는 초밥을 제거 한다음 오름차순으로 바꿔준다.

그리고 오름차순이기 때문에 이분탐색이 가능하므로 시간복잡도를 줄일수 있다.

ex) 입력

8 300000000 4 300000000

70000000 

90000000 

70000000 

300000000 

20000000 

70000000 

90000000 

250000000

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#include<stdio.h>

#define A 3001

int fish[10 * A], max = 1, realMax;           

int count;

int sort_fish[10 * A], N, d, k, c;

int real_sort_fish[10 * A];

int binary_search_fish[10 * A];

void sort() // 일단 sort_fish[]에 입력받은  fish[]를 반복되면서 오름차순으로 바꾼다.  

{

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

{

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

{

if (sort_fish[i] > sort_fish[j])

{

int temp = sort_fish[j];

sort_fish[j] = sort_fish[i];

sort_fish[i] = temp;

}

}

}

for (int i = 1; i <= N; i++)                        // 요것은 sort_fish[]는 오름차순이지만 반복되는것이 있기때문에

{                                                        //  real_sort_fish[]에 반복 되는것을 제거해줬다.

if (real_sort_fish[count] != sort_fish[i])

{

count++;

real_sort_fish[count] = sort_fish[i];

}

}

}


int binary_search(int b) // b는 찾고자 하는 수이고  이분탐색을 이용해 본래 푼 방법의 log N만큼만 시간복잡도를 곱해주는 꼴

{

int left = 1, right = count,mid;

while (1)

{

mid = (left + right) / 2;

if (real_sort_fish[mid] > b)

right = mid;

else

left = mid;

if (real_sort_fish[mid] == b)

{

return mid;

}

if (real_sort_fish[left] == b)

return left;

if (real_sort_fish[right] == b)

return right;

}

}

int main()

{


// N : 회전 초밥 벨트에 놓인 접시의 수    d : 초밥의 가짓수

scanf("%d %d %d %d", &N, &d, &k, &c); // k : 연속해서 먹는 접시의 수    c : 쿠폰 번호 (서비스)


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

{

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

sort_fish[i] = fish[i];

}

sort(); // real_sort_fish[] 배열을 만듬. <-- 오름차순으로 중복안되게 fish들을 정리해둔것.


int service = binary_search(c);            // 서비스는 어차피 받으므로 무조건 넣어둔다.

binary_search_fish[service]++;            // binary_search_fish[]에는 먹은 초밥들에 대해 저장하는 배열


for (int i = 1; i <= k; i++)                //  첫번째 접시부터 연속되게 먹을수 있는 접시들을 처음에 미리 넣어둔다.

{

int u = binary_search(fish[i]);

binary_search_fish[u]++;

if (binary_search_fish[u] == 1)

max += 1;

}


for (int i = 1; i <= N - 1; i++)                 // 저 위에 문제대로 연속해서 먹는 접시의 수가 4면 일단 위에서 1,2,3,4의 접시는 먹었고 인덱스에 저장됨

{                                                     // 그래서 2,3,4,5로 변경을 해야하는데 이때 인덱스에 1번째 접시를 인덱스에서 빼고 5번째 접시를 인덱스

if (i + k <= N)                           // 에 더하면 됨 .. 요렇게 접시 끝까지 ㄱㄱ 하는데 if문 두개 나눈이유는 작은 test case를 해보면 알겠지만

{                                            //  fish[] 배열을 넘어버리기 때문에 나눠줘야함 ..  해보면 알음 

int u = binary_search(fish[i]);

binary_search_fish[u]--;

if (binary_search_fish[u] == 0)            // 초밥이 빠져나가는 상황에서 만약 0으로 된다면 max값을 -1 한다 (꼬리쪽은 하나씩 없어짐)

max -= 1;


u = binary_search(fish[i + k]);

binary_search_fish[u]++;

if (binary_search_fish[u] == 1)            // 초밥이 더해지는 상황에서 만약 1로 된다면 max값을 +1한다 . (만약 2가된다해도  똑같은

max += 1;                                                                                                                    종류의 초밥은 취급 x)

}


else

{

int t = i + k - N;

int u = binary_search(fish[i]);

binary_search_fish[u]--;

if (binary_search_fish[u] == 0)

max -= 1;


u = binary_search(fish[t]);

binary_search_fish[u]++;

if (binary_search_fish[u] == 1)

max += 1;

}

if (realMax < max)

realMax = max;

}

printf("%d", realMax);

return 0;

}



원래 문제의 입력에서 초밥의 종류들에 한해 곱하기 천만을 한거임 . 그러므로 결과는 같아야한다.



































'알고리즘' 카테고리의 다른 글

(C++) 칵테일 쉐이크 정렬 - (ADL 추가)  (0) 2017.09.26
맨하탄 거리 측정법 과 유클리드 거리 측정법  (0) 2017.01.19
2479번 경로 찾기  (0) 2017.01.11
1699번 제곱수의 합  (0) 2017.01.08
2531번 회전초밥  (0) 2017.01.08

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

인접행렬을 만든뒤에  BFS 돌리면 된다.  BFS문제를 오랜만에 풀어서그런지 너무 코드가 더럽다.


요로코롬 인접행렬만들기





#include<stdio.h>

#define A 1001

char arr[A][31];

int map[A][A], min=1001, N, K, start, stop, Q[A][3],check[A][A],count;

int min_last,root[A],root_count;

void BFS()

{

int bun = 1, work = 0;  // Q[][0] 에는 인접행렬    Q[][1] 에는 이동 횟수

Q[1][0] = start;

while (1)

{

if (bun == work) break;

work++;

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

{

if (map[Q[work][0]][i] == 1 && i != start && check[Q[work][0]][i] == 0)

{

bun++;

check[Q[work][0]][i] = 1;

check[i][Q[work][0]] = 1;

Q[bun][0] = i;

Q[bun][1] = Q[work][1] + 1;

Q[bun][2] = work;

}

if (Q[bun][0] == stop)

{

if (Q[bun][1] < min)

{

min = Q[bun][1];

min_last = bun;

}

}

}

}

}


int main()

{

scanf("%d %d", &N, &K); // N : 코드 수 ,  K : 코드 길이

for (int i = 1; i <= N; i++) // 코드 입력

scanf("%s", &arr[i]);


scanf("%d %d", &start, &stop); // start : 시작위치 , stop : 도착위치 


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

{

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

{

for (int k = 0; k < K; k++)

{

if (arr[i][k] != arr[j][k])

count++;

}

if (count == 1)

map[i][j] = 1;

count = 0;

}

}


BFS();


while (1)

{

root[root_count] = Q[min_last][0];

min_last = Q[min_last][2];

if (min_last == 0)

break;

root_count++;

}


if (min == 1001)

printf("-1");

else

{

for (int i = min; i >= 0; i--)

printf("%d ",root[i]);

}

return 0;

}



------------------------------------------------------------------------------------------------------------------------------------------------------------------------


#include<stdio.h>

#include<math.h>

#define N 100001

int dp[N],basic = 0;


void dynamicP(int a)

{

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

{

int c = pow(basic, 2);                

if (i == pow(basic+1, 2))             //  1 or 4 or 9 or 16같은 제곱수는 바로 1을 넣어버림 . 

{                                            // basic은 1 or 4 or 9를 찾을 때 쓰는 변수이다.

dp[i] = 1;

basic++;

continue;

}

dp[i] = dp[c] + dp[i-c];               // 탐욕 알고리즘처럼 일단 바로바로 최선의 최소개수를 넣고

for (int j = 1; j <= i / 2; j++)

{

if (dp[i] > dp[i - j] + dp[j])            // 탐욕은 각각의 선택에선 최선이지만 전체적으론 최선이 아닐수도 있으니

dp[i] = dp[i - j] + dp[j];        // 조건을 주어 최적의 해를 찾아줌

}

}

}

int main()

{

int a;

scanf("%d",&a);

dynamicP(a);

printf("%d",dp[a]);

return 0;

}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------


#include<stdio.h>

int index[3001],fish[30001],max=1,realMax;            // 인덱스에 연속해서 먹는 초밥의 종류를 저장

int main()

{

int N, d, k, c; // N : 회전 초밥 벨트에 놓인 접시의 수    d : 초밥의 가짓수

scanf("%d %d %d %d",&N,&d,&k,&c); // k : 연속해서 먹는 접시의 수    c : 쿠폰 번호 (서비스)


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

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


index[c]++;                                       // c 는 service인데 어차피 내가 고르든 안고르든 무조건 먹기때문에 인덱스에 미리 저장

for (int i = 1; i <= k; i++)                    //  처음 초밥부터 연속해서 먹는 접시의 수만큼 인덱스에 넣어줌 

{

index[fish[i]]++;

if (index[fish[i]] == 1)                  //  이 조건문은 이 종류의 초밥을 처음 고른것이다 라는 것을 뜻함  (만약에 인덱스에 2가 들어갈수있는데                                                               //  어차피 같은 종류의 초밥을 2개 먹어도  똑같은 걸 먹었기 때문에 max에 영향 안줌)

max+=1;                           // 그러므로 맥스값 1 

}

for (int i = 1; i <= N-1; i++)                 // 저 위에 문제대로 연속해서 먹는 접시의 수가 4면 일단 위에서 1,2,3,4의 접시는 먹었고 인덱스에 저장됨

{                                                     // 그래서 2,3,4,5로 변경을 해야하는데 이때 인덱스에 1번째 접시를 인덱스에서 빼고 5번째 접시를 인덱스

if (i + k <= N)                           // 에 더하면 됨 .. 요렇게 접시 끝까지 ㄱㄱ 하는데 if문 두개 나눈이유는 작은 test case를 해보면 알겠지만

{                                            //  fish[] 배열을 넘어버리기 때문에 나눠줘야함 ..  해보면 알음 

index[fish[i]]-=1;

if (index[fish[i]] == 0)

max-=1;

index[fish[i + k]]+=1;

if (index[fish[i + k]] == 1)

max+=1;   

            

}

else

{

            int j = i + k - N;

            index[fish[i]]-=1;

if (index[fish[i]] == 0)

max-=1;

index[fish[j]]+=1;

if (index[fish[j]] == 1)

max+=1;

}

        if (realMax < max)

   realMax = max;

}

printf("%d",realMax);

    return 0;

}



영역을 선택후 주석 처리

Ctrl + k + c


영역을 선택후 주석 처리 해제

Ctrl + k + u


자동 정렬

Ctrl + k + f


Ctrl + k 를 먼저 누르고 있는 상태에서  c, u 를 누르면 됨


------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#include<stdio.h>


#define N 100001

long long dp[N], MAX= -1000, test, SUM;

long long arr[N];


void sum(int a)

{

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

{

SUM += arr[i];

if (MAX < SUM)

MAX = SUM;

if (SUM <= 0)

SUM = 0;

}

}

int main()

{

scanf("%lld", &test);

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

scanf("%lld", &arr[i]);

sum(test);

printf("%lld", MAX);


return 0;

}


내가 푼 방법은

10부터 -1까지 쭈루루룩 더하는데 

더하면서 합이 양수면 계속 돌진 음수면 합을 0으로 초기화후 다시 돌진 

예를 들면  10 + (-4) = 6 이다 그러므로 계속 돌진 !    ->  6 + 3 = 9 이므로 계속 돌진한다..  이렇게 쭈루룩  6 까지 계속 돌진하면 합은 21이다

근데 큰일났다.    -35라는 거대한 음수가 튀어나왔다.    더해보니  21 + (-35) =  -14 라는 음수가 나온것이다.  음수는 나쁜것이니까 버려야한다.

그러므로 0이되었고 여기서 중요한게 21이라는 것을 MAX라는 변수에 넣어놔야함 .

다시 12부터 쭈루루룩 더한다.    12 + 21 = 33(최대값)이 나오고 조건문을 통해 MAX에는 33이 대입된다.   그다음  33 + (-1)을 하고 종료된다.


여기서 주의해야하는게 MAX에다 0을 넣으면안됨.

왜냐하면 입력때 모든 수가 음수일 수가 있다.  

요로코롬  -3 -5 -2 -1 -6  이렇게 다섯가지의 숫자가 입력될수 있는데 여기서 출력은  -1이 출력되야하는데,   MAX 에 0을 넣어놨다면  마지막 출력도 0이 나와버림.   그래서 시작할때  입력할수있는 가장 적은 수인 -1000을 미리 넣어놨다.







'알고리즘 > DP(Dynamic Programming)' 카테고리의 다른 글

파도반 수열 (DP)  (0) 2016.12.21
1로 만들기 (DP)  (0) 2016.12.21
피보나치 수열 2 (DP)  (0) 2016.12.21
피보나치 수열 1 (DP)  (0) 2016.12.21

+ Recent posts