Hash

Data Structure 2019. 1. 22. 22:59



#include <stdio.h>
#include <map>
#include <algorithm>
#include "Windows.h"
using namespace std;

const int PN = 23;
const int HASH_SIZE = 10000;

int table[HASH_SIZE][50];
int hash_size = 0;
char hash_raw[30000][100];

char input[30000][100];
map<char*, int> test;

unsigned int get_key(char str[]) {
	unsigned int key = 0, p = 1;

	for (int i = 0; str[i] != 0; ++i) {
		key += (str[i] * p);
		p *= PN;
	}

	return (key % HASH_SIZE);
}

int my_strcamp(char a[], char b[]) {
	int i = 0, j = 0;
	while (a[i]) {
		if (a[i++] != b[j++]) {
			--i, --j;
			break;
		}
	}
	return (a[i] - b[j]);
}

int contain(char str[]) {
	unsigned int key = get_key(str);
	int size = table[key][0];
	for (int i = 1; i <= size; ++i) {
		int pos = table[key][i];
		if (my_strcamp(hash_raw[pos], str) == 0) {
			return pos;
		}
	}
	return -1;
}

void add(char str[]) {
	int len = 0;
	for (len = 0; str[len] != 0; ++len) {
		hash_raw[hash_size][len] = str[len];
	}
	hash_raw[hash_size][len] = 0;

	unsigned int key = get_key(str);
	int& size = table[key][0];
	table[key][++size] = hash_size;

	++hash_size;
}

bool remove(char str[]) {
	unsigned int key = get_key(str);
	int& size = table[key][0];
	for (int i = 1; i <= size; ++i) {
		int pos = table[key][i];
		if (my_strcamp(hash_raw[pos], str) == 0) {
			for (int j = i + 1; j <= size; ++j) {
				table[key][j - 1] = table[key][j];
			}
			--size;
			return true;
		}
	}
	return false;
}

int make_int(int min, int max) {
	return (rand() % (max - min)) + min;
}

char make_char() {
	int val = rand() % 52;
	if (val < 26) {
		return static_cast<char>('a' + val);
	}
	return static_cast<char>('A' + val - 26);
}

int main()
{
	for (int i = 0; i < 30000; ++i) {
		int len = make_int(10, 100);
		for (int j = 0; j < len; ++j) {
			input[i][j] = make_char();
		}
		input[i][len] = 0;

		if (contain(input[i]) == -1) {
			add(input[i]);
		}
		test[input[i]] = i;


		if (i > 20000) {
			int cmd = make_int(0, 5);
			int index = make_int(0, i);
			if (cmd == 0) {
				if (contain(input[index]) != -1) {
					remove(input[index]);
				}

				test.erase(input[index]);
			}
			if (cmd == 1) {
				int my_pos = contain(input[index]);
				map<char*, int>::iterator iter = test.find(input[index]);
				int stl_pos = -1;
				if (iter != test.end()) {
					stl_pos = iter->second;
				}

				if (my_pos != stl_pos) {
					printf("find error!!!\n");
				}
			}
		}
	}

	int my_hash_size = 0;
	for (int i = 0; i < HASH_SIZE; ++i) {
		my_hash_size += table[i][0];
	}

	if (my_hash_size != test.size()) {
		printf("remove error!!!\n");
	}

	return 0;
}


설정

트랙백

댓글

Heap

Data Structure 2019. 1. 11. 22:36





#include <stdio.h>
#include <algorithm>
#include "Windows.h"
using namespace std;

int heap_size;
int heap[10000];

void push(int data) {
	int target = heap_size + 1;
	while (target != 1 && heap[target / 2] < data) {
		heap[target] = heap[target / 2];
		target /= 2;
	}
	heap[target] = data;
	++heap_size;
}

void pop() {
	int parent = 1, child = 2;
	int temp = heap[heap_size];
	while (child < heap_size) {
		if (child + 1 < heap_size && heap[child] < heap[child + 1]) {
			++child;
		}
		if (temp >= heap[child]) {
			break;
		}
		heap[parent] = heap[child];
		parent = child;
		child *= 2;
	}
	heap[parent] = temp;
	--heap_size;
}

bool comp(int a, int b) {
	return (a > b);
}

int main()
{
	int a[10000], b[10000];
	for (int i = 0; i < 9999; ++i) {
		a[i] = rand() % 10000;
		b[i] = a[i];
	}
	sort(a, a + 9999, comp);

	for (int i = 0; i < 9999; ++i) {
		push(b[i]);
	}

	for (int i = 0; i < 9999; ++i) {
		if (a[i] != heap[1]) {
			printf("not heap!!!\n");
		}
		pop();
	}

	return 0;
}


설정

트랙백

댓글

[삼성 SW 역량 테스트] 아기 상어





#include <stdio.h>
#include <queue>
using namespace std;

struct SHARK {
	int y, x, time;
};

int n;
int map[20][20];

int shark_size, shark_eat;
SHARK shark;

const int dy[] = { 0, 0, -1, +1 };
const int dx[] = { -1, +1, 0, 0 };

int main()
{
	scanf("%d", &n);
	for (int y = 0; y < n; ++y) {
		for (int x = 0; x < n; ++x) {
			scanf("%d", &map[y][x]);
			if (map[y][x] == 9) {
				shark.y = y, shark.x = x, shark.time = 0;
				shark_size = 2, shark_eat = 0;
				map[y][x] = 0;
			}
		}
	}

	bool is_update = true;
	while (is_update) {
		is_update = false;

		bool visited[20][20] = { false, };
		queue q;
		visited[shark.y][shark.x] = true;
		q.push(shark);

		SHARK candi;
		candi.y = 20, candi.time = -1;
		while (!q.empty()) {
			SHARK cur = q.front();	q.pop();

			if (candi.time != -1 && candi.time < cur.time) {
				break;
			}

			if (map[cur.y][cur.x] < shark_size && map[cur.y][cur.x] != 0) {
				is_update = true;
				if (candi.y > cur.y || (candi.y == cur.y && candi.x > cur.x)) {
					candi = cur;
				}
			}

			for (int dir = 0; dir < 4; ++dir) {
				SHARK next;
				next.y = cur.y + dy[dir];
				next.x = cur.x + dx[dir];
				next.time = cur.time + 1;

				if (next.y < 0 || next.y >= n || next.x < 0 || next.x >= n) {
					continue;
				}

				if (visited[next.y][next.x] == false && shark_size >= map[next.y][next.x]) {
					visited[next.y][next.x] = true;
					q.push(next);
				}
			}
		}

		if (is_update) {
			shark = candi;
			++shark_eat;
			if (shark_eat == shark_size) {
				++shark_size;
				shark_eat = 0;
			}
			map[shark.y][shark.x] = 0;
		}
	}

	printf("%d\n", shark.time);

	return 0;
}


설정

트랙백

댓글

[삼성 SW 역량 테스트]나무 재태크





#include <stdio.h>
#include <algorithm>
using namespace std;

struct TREE {
	int y, x, age;
};

bool cmp(TREE& a, TREE& b) {
	return (a.age < b.age);
}

struct QUEUE {
	int f, b;
	TREE tree[684000];

	QUEUE() {
		init();
	}

	void init() {
		f = 0, b = 0;
	}

	bool isempty() {
		return (f == b);
	}

	void push(TREE val) {
		tree[b++] = val;
	}

	void pop() {
		++f;
	}

	TREE front() {
		return tree[f];
	}

	int size() {
		return (b - f);
	}
};

int n, m, k;
QUEUE tree[2];
QUEUE new_tree;
QUEUE dead_tee, birth_of_child_tree;

TREE init_tree[100];

int map[10][10], add[10][10];

int main()
{
	scanf("%d %d %d", &n, &m, &k);
	for (int y = 0; y < n; ++y) {
		for (int x = 0; x < n; ++x) {
			scanf("%d", &add[y][x]);
			map[y][x] = 5;
		}
	}

	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", &init_tree[i].y, &init_tree[i].x, &init_tree[i].age);
		init_tree[i].y--, init_tree[i].x--;
	}

	sort(init_tree, init_tree + m, cmp);
	
	int cur = 0, next = 0;
	for (int i = 0; i < m; ++i) {
		tree[cur].push(init_tree[i]);
	}
	
	for (int i = 0; i < k; ++i) {

		next = (cur + 1) % 2;
		
		dead_tee.init();
		birth_of_child_tree.init();
		tree[next].init();

		while (!new_tree.isempty()) {
			TREE cur_tree = new_tree.front(); new_tree.pop();

			if (map[cur_tree.y][cur_tree.x] >= cur_tree.age) {
				map[cur_tree.y][cur_tree.x] -= cur_tree.age;

				++cur_tree.age;
				tree[next].push(cur_tree);
			}
			else {
				dead_tee.push(cur_tree);
			}
		}

		while (!tree[cur].isempty()) {
			TREE cur_tree = tree[cur].front(); tree[cur].pop();

			if (map[cur_tree.y][cur_tree.x] >= cur_tree.age) {
				map[cur_tree.y][cur_tree.x] -= cur_tree.age;

				++cur_tree.age;
				tree[next].push(cur_tree);

				if ((cur_tree.age % 5) == 0) {
					birth_of_child_tree.push(cur_tree);
				}
			}
			else {
				dead_tee.push(cur_tree);
			}
		}

		while (!dead_tee.isempty()) {
			TREE cur_tree = dead_tee.front();	dead_tee.pop();
			map[cur_tree.y][cur_tree.x] += (cur_tree.age / 2);
		}

		const int dy[] = { -1, -1, -1, 0, 0, +1, +1, +1 };
		const int dx[] = { -1, 0, +1, -1, +1, -1, 0, +1 };

		new_tree.init();
		while (!birth_of_child_tree.isempty()) {
			TREE cur_tree = birth_of_child_tree.front();	birth_of_child_tree.pop();
			for (int dir = 0; dir < 8; ++dir) {
				TREE next_tree;
				next_tree.y = cur_tree.y + dy[dir];
				next_tree.x = cur_tree.x + dx[dir];
				next_tree.age = 1;
				if (next_tree.y < 0 || next_tree.y >= n || next_tree.x < 0 || next_tree.x >= n) {
					continue;
				}
				new_tree.push(next_tree);
			}
		}

		for (int y = 0; y < n; ++y) {
			for (int x = 0; x < n; ++x) {
				map[y][x] += add[y][x];
			}
		}

		cur = next;
	}

	printf("%d\n", tree[next].size() + new_tree.size());

	return 0;
}


설정

트랙백

댓글

[삼성 SW 역량 테스트] 인구 이동





#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;

struct POSI {
	int y, x;
};

int n, l, r;
int map[50][50];

void create_area(int sy, int sx, int status[][50], int index, int& count, int& sum) {
	int visited[50][50] = { 0, };

	const int dy[] = { 0, 0, -1, +1 };
	const int dx[] = { -1, +1, 0, 0 };

	queue<posi> q;
	POSI head;
	head.y = sy;
	head.x = sx;
	visited[sy][sx] = 1;
	q.push(head);

	while (!q.empty()) {
		POSI cur = q.front();	q.pop();

		status[cur.y][cur.x] = index;
		++count;
		sum += map[cur.y][cur.x];

		for (int dir = 0; dir < 4; ++dir) {
			POSI next;
			next.y = cur.y + dy[dir];
			next.x = cur.x + dx[dir];

			if (next.y < 0 || next.y >= n || next.x < 0 || next.x >= n) {
				continue;
			}

			int delta = abs(map[cur.y][cur.x] - map[next.y][next.x]);
			if (visited[next.y][next.x] == 0 && l <= delta && delta <= r) {
				visited[next.y][next.x] = 1;
				q.push(next);
			}
		}
	}
}


int main()
{
	scanf("%d %d %d", &n, &l, &r);
	for (int y = 0; y < n; ++y) {
		for (int x = 0; x < n; ++x) {
			scanf("%d", &map[y][x]);
		}
	}

	int ret = 0;
	bool is_update = true;
	while (is_update) {
		is_update = false;

		int status[50][50] = { 0, };
		int area_index = 0;
		int count[2501] = { 0, };
		int sum[2501] = { 0, };
		for (int y = 0; y < n; ++y) {
			for (int x = 0; x < n; ++x) {
				if (status[y][x] == 0) {
					++area_index;
					create_area(y, x, status, area_index, count[area_index], sum[area_index]);
				}
			}
		}

		for (int y = 0; y < n; ++y) {
			for (int x = 0; x < n; ++x) {
				int  index = status[y][x];
				int avg = sum[index] / count[index];
				if (map[y][x] != avg) {
					map[y][x] = avg;
					is_update = true;					
				}
			}
		}
		if (is_update) {
			++ret;
		}
	}

	printf("%d\n", ret);
	return 0;
}


설정

트랙백

댓글