기본 자료형을 사용한 오름차순 정렬

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int compare(const void *x,const void *y)
{
	return *(int *)x>*(int *)y?1:-1;
}

int main(void)
{
	int N=10, arr[10];
	srand((unsigned)time(NULL));

	for(int n=0;n<N;++n)
		arr[n]=rand()%100;

	qsort((void *)arr,(size_t)N,sizeof(int),compare);

	for(int n=0;n<N;++n)
		printf("%d ", arr[n]);

	return 0;
}

 

구조체를 사용한 오름차순 정렬

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct
{
	int primary, secondary;
}
dimension;

int compare(const void *x,const void *y)
{
	return ((dimension *)x)->primary<((dimension *)y)->primary?-1:((dimension *)x)->primary>((dimension *)y)->primary?1:((dimension *)x)->secondary<((dimension *)y)->secondary?-1:1;
}

int main(void)
{
	int N=30;
	dimension arr[30];
	srand((unsigned)time(NULL));

	for(int n=0;n<N;++n)
	{
		arr[n].primary=rand()%5;
		arr[n].secondary=rand()%5;
	}

	qsort((void *)arr,(size_t)N,sizeof(dimension),compare);

	for(int n=0;n<N;++n)
		printf("%d %d\n", arr[n].primary, arr[n].secondary);

	return 0;
}
728x90

길이가 n인 정수의 배열 A[0..n-1]가 있다. A[a] + A[a+1] + … + A[b]의 값을 최대화하는 구간 (a,b)를 찾는 방법을 Divide-and-Conquer 전략을 이용하여 설계하고 분석하라.
예를 들어, 배열 A가 아래와 같이 주어졌을 경우
(n=10), {31,-41,59,26,-53,58,97,-93,-23 ,84}
답은 a=2, b=6 인 경우의 59+26-53+58+97=187이 된다.


더보기

Solution

O(n^3)의 풀이

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int maximum_partial_array(int *arr,int size)
{
	int max_value=arr[0], max_a=0, max_b=0;

	for(int i=0;i<size;i++)
		for(int j=i;j<size;j++)
		{
			int sum=0;

			for(int k=i;k<=j;k++)
				sum+=arr[k];

			max_a=max_value>sum?max_a:i;
			max_b=max_value>sum?max_b:j;
			max_value=max_value>sum?max_value:sum;
		}

	printf("maximum sum: %d\n",max_value);
	return 100*max_a+max_b;
}

int main(void)
{
	int size, *arr=NULL, ab;
	srand((unsigned)time(NULL));

	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	printf("initial array: ");
	for(int i=0;i<size;i++)
	{
		arr[i]=rand()%200-100;
		printf("%d ", arr[i]);
	}
	printf("\n");

	ab=maximum_partial_array(arr,size);
	printf("a:%d, b:%d\n", ab/100, ab%100);

	free(arr);
	return 0;
}

 

O(n^2)의 풀이

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int maximum_partial_array(int *arr,int size)
{
	int max_value=arr[0], max_a=0, max_b=0;

	for(int i=0;i<size;i++)
	{
		int sum=0;

		for(int j=i;j<size;j++)
		{
			sum+=arr[j];

			max_a=max_value>sum?max_a:i;
			max_b=max_value>sum?max_b:j;
			max_value=max_value>sum?max_value:sum;
		}
	}

	printf("maximum sum: %d\n",max_value);
	return 100*max_a+max_b;
}

int main(void)
{
	int size, *arr=NULL, ab;
	srand((unsigned)time(NULL));

	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	printf("initial array: ");
	for(int i=0;i<size;i++)
	{
		arr[i]=rand()%200-100;
		printf("%d ", arr[i]);
	}
	printf("\n");

	ab=maximum_partial_array(arr,size);
	printf("a:%d, b:%d\n", ab/100, ab%100);

	free(arr);
	return 0;
}

 

O(nlogn)의 풀이: Divide-and-Conquer 전략

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

long long int maximum_partial_array(int *arr,int low,int high)
{
	int mid=(low+high)/2, left_a, left_b, right_a, right_b, left_part_a=(low+high)/2+1, right_part_b=(low+high)/2, sum=0;
	long long int left, right, left_part_value=-999999, right_part_value=-999999;

	if(low==high)
		return 10000*arr[low]+101*low;

	left=maximum_partial_array(arr,low,mid);
	right=maximum_partial_array(arr,mid+1,high);
	left_a=(left/100)%100;
	left_b=left%100;
	right_a=(right/100)%100;
	right_b=right%100;

	for(int i=mid;i>=low;i--)
	{
		sum+=arr[i];
		left_part_a=left_part_value>sum?left_part_a:i;
		left_part_value=left_part_value>sum?left_part_value:sum;
	}

	sum=0;
	for(int i=mid+1;i<=high;i++)
	{
		sum+=arr[i];
		right_part_b=right_part_value>sum?right_part_b:i;
		right_part_value=right_part_value>sum?right_part_value:sum;
	}

	if(left/10000>=right/10000 && left/10000>=left_part_value+right_part_value)
		return left;
	else if(left_part_value+right_part_value>=left/10000 && left_part_value+right_part_value>=right/10000)
		return 10000*(left_part_value+right_part_value)+100*left_part_a+right_part_b;
	else
		return right;
}

int main(void)
{
	int size, *arr=NULL;
	long long int result;
	srand((unsigned)time(NULL));

	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	printf("initial array: ");
	for(int i=0;i<size;i++)
	{
		arr[i]=rand()%200-100;
		printf("%d ", arr[i]);
	}
	printf("\n");

	result=maximum_partial_array(arr,0,size-1);
	printf("a:%lld, b:%lld, sum:%lld\n", (result/100)%100, result%100, result/10000);

	free(arr);
	return 0;
}

 

O(n)의 풀이

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int maximum_partial_array(int *arr,int size)
{
	int max_value=arr[0], max_a=0, max_b=0, sum=0, sum_a=0, sum_b=0;

	for(int i=0;i<size;i++)
	{
		sum_a=arr[i]+sum>arr[i]?sum_a:i;
		sum_b=i;
		sum=arr[i]+sum>arr[i]?arr[i]+sum:arr[i];

		max_a=max_value>=sum?max_a:sum_a;
		max_b=max_value>=sum?max_b:sum_b;
		max_value=max_value>=sum?max_value:sum;
	}

	printf("maximum sum: %d\n",max_value);
	return 100*max_a+max_b;
}

int main(void)
{
	int size, *arr=NULL, ab;
	srand((unsigned)time(NULL));

	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	printf("initial array: ");
	for(int i=0;i<size;i++)
	{
		arr[i]=rand()%200-100;
		printf("%d ", arr[i]);
	}
	printf("\n");

	ab=maximum_partial_array(arr,size);
	printf("a:%d, b:%d\n", ab/100, ab%100);

	free(arr);
	return 0;
}

 

728x90

입력으로 주어지는 배열 A[0..n-1]은 오름차순으로 정렬되어 있으며 n 개의 서로 다른 정수들을 원소로 가진다. 즉, A[0] < A[1] < … < A[n-1] 이다. 원소들은 양수, 음수 혹은 0일 수 있다.

(a) A[i]=i를 만족하는 index i가 존재하는지 알고 싶다. 그런 index i가 존재하면 찾아서 i를 출력하고, 없으면 -1을 출력하는 알고리즘을 설계하시오.

(b) 배열 A의 원소들이 모두 0 혹은 양수라는 조건이 성립한다면, 위의 문제를 해결하는 더 빠른 알고리즘이 가능하다. 어떻게 할 수 있을까?


더보기

Solution

(a)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void value_equals_index(int *arr,int current,int size,int count)
{
	if(current>=size || arr[current]>current)
	{
		if(count==0)
			printf("-1");
		printf("\n");
		return;
	}
	else if(arr[current]==current)
	{
		printf("%d ", current);
		value_equals_index(arr,current+1,size,count+1);
	}
	else
		value_equals_index(arr,current+1,size,count);
}

int main(void)
{
	int size, *arr=NULL;
	srand((unsigned)time(NULL));

	printf("size: ");
	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	for(int i=0;i<size;i++)
	{
		int flag=0;

		do
		{
			flag=0;
			arr[i]=rand()%100-50;

			for(int j=0;j<i;j++)
				if(arr[i]==arr[j])
				{
					flag=1;
					break;
				}
		}
		while(flag);
	}

	for(int i=0;i<size-1;i++)
		for(int j=i+1;j<size;j++)
			if(arr[i]>arr[j])
			{
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}

	printf("sorted array: ");
	for(int i=0;i<size;i++)
		printf("%d ", arr[i]);
	printf("\n");

	value_equals_index(arr,0,size,0);

	free(arr);
	return 0;
}

 

(b)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void value_equals_index(int *arr,int current,int size,int count)
{
	if(current>=size || arr[current]!=current)	//이 부분이 바뀜: >에서 !=으로 -> 더 빠른 종료조건
	{
		if(count==0)
			printf("-1");
		printf("\n");
		return;
	}
	else if(arr[current]==current)
	{
		printf("%d ", current);
		value_equals_index(arr,current+1,size,count+1);
	}
	else
		value_equals_index(arr,current+1,size,count);
}

int main(void)
{
	int size, *arr=NULL;
	srand((unsigned)time(NULL));

	printf("size: ");
	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	for(int i=0;i<size;i++)
	{
		int flag=0;

		do
		{
			flag=0;
			arr[i]=rand()%100;

			for(int j=0;j<i;j++)
				if(arr[i]==arr[j])
				{
					flag=1;
					break;
				}
		}
		while(flag);
	}

	for(int i=0;i<size-1;i++)
		for(int j=i+1;j<size;j++)
			if(arr[i]>arr[j])
			{
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}

	printf("sorted array: ");
	for(int i=0;i<size;i++)
		printf("%d ", arr[i]);
	printf("\n");

	value_equals_index(arr,0,size,0);

	free(arr);
	return 0;
}
728x90

“정렬 후 회전된 배열”이란 (5, 8, 9, 2, 3, 4)와 같은 배열을 말한다. 즉, 정렬이 된 후에 회전 연산이 0회 이상 적용된 배열이다. 회전 연산이란 배열의 마지막 원소가 처음으로 이동하고 나머지 원소들이 오른쪽으로 한 칸씩 이동하는 것을 말한다. 예를 들어, (2, 3, 4, 5, 8, 9)는 정렬된 배열이고 여기에 회전 연산을 1회 적용하면 (9, 2, 3, 4, 5, 8)이 되고 여기에 회전 연산을 추가로 2회 적용하면 (5, 8, 9, 2, 3, 4)가 된다. 따라서 (5, 8, 9, 2, 3, 4)는 정렬 후 회전된 배열이다.

(a) 길이가 n 인 정렬후 회전된 배열 A[0..n-1]가 주어질 때, 이 배열 A 에서 최댓값을 찾는 알고리즘을 설계하시오.

(b) 정렬후 회전된 배열 A[0..n-1]가 회전연산을 몇번 적용한 것인지 알아내는 알고리즘을 설계하시오.

(c) 정렬후 회전된 배열 A[0..n-1]와 k 가 주어질 때, A 안에서 k 를 탐색하는 알고리즘을 설계하시오. 즉, A 의 원소 중에 k 가 있으면 그 위치(index)를 출력하고 없으면 -1 을 출력합니다.


더보기

Solution

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int find_max(int *arr,int size)			//(a)
{
	for(int i=1;i<size;i++)
		if(arr[i-1]>arr[i])
			return arr[i-1];
	return arr[size-1];
}

int rotated_count(int *arr,int size)	//(b)
{
	for(int i=1;i<size;i++)
		if(arr[i-1]>arr[i])
			return i;
	return 0;
}

int find_k(int *arr,int k,int size)		//(c)
{
	for(int i=0;i<size;i++)
		if(arr[i]==k)
			return i;
	return -1;
}

int main(void)
{
	int size, *arr=NULL, k,random;
	srand((unsigned)time(NULL));

	printf("size: ");
	scanf("%d", &size);
	arr=(int *)malloc(size*sizeof(int));

	printf("initial array: ");
	for(int i=0;i<size;i++)
	{
		arr[i]=rand()%100;
		printf("%d ", arr[i]);
	}
	printf("\n");

	for(int i=0;i<size-1;i++)			//sort array
		for(int j=i+1;j<size;j++)
			if(arr[i]>arr[j])
			{
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}
	printf("sorted array: ");
	for(int i=0;i<size;i++)
		printf("%d ", arr[i]);
	printf("\n");

	random=rand()%size;				//rotate array
	printf("random:%d\n", random);
	for(int i=0;i<random;i++)
	{
		int temp=arr[size-1];
		for(int j=size-1;j>=0;j--)
			arr[j]=arr[j-1];
		arr[0]=temp;
	}
	printf("rotated array: ");
	for(int i=0;i<size;i++)
		printf("%d ", arr[i]);
	printf("\n");

	printf("max:%d,rotated count:%d\n",find_max(arr,size),rotated_count(arr,size));
	printf("k: ");
	scanf("%d", &k);
	printf("%d\n",find_k(arr,k,size));

	free(arr);
	return 0;
}
728x90

배열의 값은 랜덤으로 넣고 재귀함수를 이용했다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int sum(int *arr,int summation,int N)
{
	return N==0?summation+arr[0]:sum(arr,summation+arr[N],N-1);
}

int main(void)
{
	int *array=NULL, count, i;
	srand((unsigned)time(NULL));

	scanf("%d", &count);
	array=(int *)malloc(count*sizeof(int));

	printf("배열: ");
	for(i=0;i<count;i++)
	{
		array[i]=rand()%100;
		printf("%d ", array[i]);
	}
	printf("\n");

	printf("합계: %d\n", sum(array,0,count-1));

	free(array);
	return 0;
}
728x90

배열의 값은 랜덤으로 넣고 재귀함수를 이용했다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int find_min(int *arr,int min,int minValue,int start,int end)
{
	return start==end-1?(minValue<arr[start]?min:start):find_min(arr,minValue<arr[start]?min:start,minValue<arr[start]?minValue:arr[start],start+1,end);
}

void selection_sort(int *arr,int start,int end)
{
	int min, temp;

	if(start<end-1)
	{
		min=find_min(arr,start,arr[start],start,end);

		temp=arr[min];
		arr[min]=arr[start];
		arr[start]=temp;

		selection_sort(arr,start+1,end);
	}
}

int main(void)
{
	int *array=NULL, count, i;
	srand((unsigned)time(NULL));

	scanf("%d", &count);
	array=(int *)malloc(count*sizeof(int));

	printf("초기 배열:\n");
	for(i=0;i<count;i++)
	{
		array[i]=rand()%100;
		printf("%2d ", array[i]);
	}
	printf("\n");

	selection_sort(array,0,count);
	printf("정렬 후:\n");
	for(i=0;i<count;i++)
		printf("%2d ", array[i]);
	printf("\n");

	free(array);
	return 0;
}
728x90

배열의 값은 랜덤으로 넣었다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void reverse(int *arr,int k,int size)
{
	int i, temp;

	for(i=0;i<k/2;i++)
	{
		temp=arr[i];
		arr[i]=arr[k-i-1];
		arr[k-i-1]=temp;
	}
    
	printf("reversed: ");
	for(i=0;i<size;i++)
		printf("%d ", arr[i]);
	printf("\n");
}

void pancake_sort(int *arr,int count,int size)
{
	int i=0, j, flag;

	if(count>0)
	{
		while(arr[i]!=count)
			i++;

		reverse(arr,i+1,size);
		reverse(arr,count,size);

		flag=1;
		for(j=1;j<size;j++)
			if(arr[j-1]>arr[j])
			{
				flag=0;
				break;
			}
		if(flag)
			return;
		pancake_sort(arr,count-1,size);
	}
}

int main(void)
{
	int *array=NULL, count, i, j, flag;
	srand((unsigned)time(NULL));

	scanf("%d", &count);
	array=(int *)malloc(count*sizeof(int));

	printf("초기 배열:\n");
	for(i=0;i<count;i++)
	{
		do
		{
			flag=0;
			array[i]=rand()%count+1;
			for(j=0;j<i;j++)
				if(array[i]==array[j])
				{
					flag=1;
					break;
				}
		}
		while(flag==1);
		printf("%d ", array[i]);
	}
	printf("\n");

	pancake_sort(array,count,count);
	printf("정렬 후:\n");
	for(i=0;i<count;i++)
		printf("%d ", array[i]);
	printf("\n");

	free(array);
	return 0;
}

 

728x90

배열의 값은 랜덤으로 넣고 재귀함수를 이용했다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int min(int *arr,int minimum,int N)
{
	if(N==0)
		return minimum<arr[0]?minimum:arr[0];
	else
		return min(arr,minimum<arr[N]?minimum:arr[N],N-1);
}

int main(void)
{
	int *array=NULL, count, i;
	srand((unsigned)time(NULL));

	scanf("%d", &count);
	array=(int *)malloc(count*sizeof(int));
    
	printf("배열: ");

	for(i=0;i<count;i++)
	{
		array[i]=rand()%100;
		printf("%d ", array[i]);
	}
	printf("\n");

	printf("최솟값:%d\n", min(array,array[0],count-1));
    
	free(array);
	return 0;
}
728x90

+ Recent posts