forum

프로그래밍 thread

posted
Total Posts
36
Topic Starter
A BCDe
프로그래밍에 대해 이야기하는 쓰레드입니다!

다양한 프로그래밍 관련 이야기들을 올려봅시다!

궁금한 것을 물어봐도 되고, 코딩하다 막히는 부분에 대해 이야기해봐도 됩니다!

참고로 저는 C계열(C/C++/C#)을 주로 쓰고, 자바와 파이썬은 부로 씁니다.
Sylphi
전 취미, 단순한 작업용으로 예전에 배웠었기에 그닥 잘하진 못합니다만 주로 쓰는건 C/C++, C#, Go 정도네요.
Python은 약간 되긴 하는데, 솔직히 잘은 모르겠...

그러고보니 osu! 하시는 분들중에는 프로그래밍 전공으로 배우시는분들이 많더군요
kai99
저는 C를 공부하는것으로 시작해서 학교에서 자바, 지금은 python으로 디스코드에서 봇을 돌리고 있어요.
파이썬은... 저도 역시 그냥 필요할 때 찾아보고 나머지는 그냥 땜빵해서....... 안다고 말할 수 있을지 모르겠네요.
guineaQ
저도 주로 C 스타일 언어들 (C/C++, Java) 많이 쓰는데 요즘 들어서 OOP 언어 보단 C가 더 끌리네요, 어설프게 OOP 스타일로 디자인해서 코딩하는 것보단 그냥 대충(...) 하는게 더 빨라서

그리고 이번 학기는 Javascript WebGL 하느라 죽는줄
Topic Starter
A BCDe
저는 친구따라 강남간다는 말 따라 친구따라 코딩 시작했는데, 이제는 취미라기기보다는 전공으로 가지고 갈 생각도 하고 있습니다.
개인적으로는 자바보다는 c#인 것 같습니다. 아직은 Java가 더 많이 쓰이기는 하지만 아마 자바의 시대도 끝나고 있지 않나 싶네여

> 파이썬은 기계학습할 때만 씁시다! 쓰기는 편해도 너무 느려서..
>> Go를 쓰시는 분은 처음봐요!
Sylphi

A BCDe wrote:

>> Go를 쓰시는 분은 처음봐요!
그저 컴퓨터에 환경을 저거 3개만 해둬서 하고있는거긴 합니다만...
지금은 그마저도 포맷하고나서 설정하기 귀찮단 이유로 멍때리고 있음
Topic Starter
A BCDe

Sylphi wrote:

그저 컴퓨터에 환경을 저거 3개만 해둬서 하고있는거긴 합니다만...
지금은 그마저도 포맷하고나서 설정하기 귀찮단 이유로 멍때리고 있음
많이 설정할 필요없는 비주얼 스튜디오 쓰세요..!
Luel Roseline


고작 그거야 설마
스크립트 키드들이 득실거리는구나...어설프군
Kawashiro
형님들 제가 과제가 막혀서 그런데 좀 도와주세용 ㅠㅠ

문제
산타의 양말 찾기
50개의 선물 상자 중에 한 개의 상자에는 산타의 양말이 들어 있다. 다음의 조건에 맞는 양말이 들어있는 상자를 찾는 프로그램을 작성하시오.
1. 상자는 배열을 이용하여 구현, 선물 상자의 무게는 10 양말 상자의 무
게는 1로 가정
2. 상자를 여는 횟수는 1번으로 제한 (배열을 탐색하여 1인 것을 찾는 방
법은 불가)
3. 상자들의 무게를 비교하여 범위를 제한하는 함수는 재귀 함수로 작성(
비교하는 횟수는 6번 이하)

일단 조교님 힌트로는 이진 탐색이랑 비슷한 방법으로 하면 된다는데

도오오오오오오저히 답이 안나옵니다 ㅠㅠ

일단 지금까지 짠 코드는 이따 집가서 보여드릴게용 ㅠㅠ
Sylphi

UnLock- wrote:

형님들 제가 과제가 막혀서 그런데 좀 도와주세용 ㅠㅠ

문제
산타의 양말 찾기
50개의 선물 상자 중에 한 개의 상자에는 산타의 양말이 들어 있다. 다음의 조건에 맞는 양말이 들어있는 상자를 찾는 프로그램을 작성하시오.
1. 상자는 배열을 이용하여 구현, 선물 상자의 무게는 10 양말 상자의 무
게는 1로 가정
2. 상자를 여는 횟수는 1번으로 제한 (배열을 탐색하여 1인 것을 찾는 방
법은 불가)
3. 상자들의 무게를 비교하여 범위를 제한하는 함수는 재귀 함수로 작성(
비교하는 횟수는 6번 이하)

일단 조교님 힌트로는 이진 탐색이랑 비슷한 방법으로 하면 된다는데

도오오오오오오저히 답이 안나옵니다 ㅠㅠ

일단 지금까지 짠 코드는 이따 집가서 보여드릴게용 ㅠㅠ
일단 단순하게 수학적으로 생각해보면, 양측으로 나눠서 더 무거운쪽을 다시한번 그런식으로 해보는 방법으로 해보면 될거에요
공책에 한번 직접 해봤는데, 50개 기준으로는 6번정도만 확인하면 충분히 알수 있더군요

e.g. (25, 25) -> (12, 13) -> (6, 7) -> (3, 4) -> (2, 2) -> (1, 1)

50의 경우엔 25, 25로 나눈 다음부터는 똑같이 나눌수가 없는 상황이 되긴 하는데
어짜피 상자 하나의 무게가 10이라면 한개가 더 있다고 해서 문제가 되진 않을겁니다

12, 13을 기준으로 봤을때, 만약 12쪽에 10이라는 무게의 상자가 있다면 각각 무게는 21, 13이 될테고
13쪽에 10이라는 무게의 상자가 있다면 각각 무게는 12, 22가 될테니까요.

코드가 이상하게 되긴 했지만, 굳이 작성한다면 이런느낌이 되겠네요

C++
#include <iostream>
#include <algorithm>

int nyaa(int *arr, unsigned int size, int val) {
if (size == 0)
return -1;

if (size == 1 && arr[0] == val) {
return 0;
}
else if (size == 1 && arr[0] != val) {
return -1;
}

unsigned int del = size / 2;
int left = std::accumulate(arr, arr + del, 0, std::plus<int>());
int right = std::accumulate(arr + del, arr + size, 0, std::plus<int>());

if (left > right) {
int ret = nyaa(arr, del, val);
return (ret != -1) ? (size_t)arr + (size_t)ret - (size_t)arr : ret;
}
else if (left < right) {
int ret = nyaa(arr + del, size - del, val);
return (ret != -1) ? (size_t)arr + (size_t)del + (size_t)ret - (size_t)arr : ret;
}
else {
return -1;
}
}

int main()
{
int arr[50];
std::fill_n(arr, 50, 1);

srand(time(0));
arr[rand()%50] = 10;

int search = nyaa(arr, 50, 10);
if (search == -1) {
std::cout << "Not found" << std::endl;
}
else {
std::cout << "Found: arr[" << search << "] == " << arr[search] << std::endl;
}
}
Topic Starter
A BCDe

UnLock- wrote:

형님들 제가 과제가 막혀서 그런데 좀 도와주세용 ㅠㅠ

문제
산타의 양말 찾기
50개의 선물 상자 중에 한 개의 상자에는 산타의 양말이 들어 있다. 다음의 조건에 맞는 양말이 들어있는 상자를 찾는 프로그램을 작성하시오.
1. 상자는 배열을 이용하여 구현, 선물 상자의 무게는 10 양말 상자의 무
게는 1로 가정
2. 상자를 여는 횟수는 1번으로 제한 (배열을 탐색하여 1인 것을 찾는 방
법은 불가)
3. 상자들의 무게를 비교하여 범위를 제한하는 함수는 재귀 함수로 작성(
비교하는 횟수는 6번 이하)

일단 조교님 힌트로는 이진 탐색이랑 비슷한 방법으로 하면 된다는데

도오오오오오오저히 답이 안나옵니다 ㅠㅠ

일단 지금까지 짠 코드는 이따 집가서 보여드릴게용 ㅠㅠ
답이 좀 늦은것인지도 모르겠는데요

저는 이 상자들을 3개로 나눠봤습니다.

그러니까, 50개의 상자면 17,17, 16 이렇게 세 더미로 최대한 균등하게 나눠보자는 것입니다.

그럼 첫번째 17개 상자들과 두번째 17개 상자들을 비교하면

1) 무게가 같다
2) 첫번째가 무겁다
3) 두번째가 무겁다

이렇게 세가지가 있겠죠.

1)의 경우에는 16개짜리 더미에 양말이 들어있는 것이겠죠.
2)의 경우에는 첫번째 17개 상자들 중 양말이 있겠죠.
3)의 경우에는 두번째 17개 상자들 중 양말이 있겠죠.

17, 17, 16이 아니더라도 16, 16, 18도 되겠죠.

이런 식으로 범위를 줄여나갈 수 있습니다.

이러면 최대 4번이면 양말을 찾을 수 있습니다.

c++ 코드입니다.

#include <stdio.h>
#include <random> // 랜덤을 위한 헤더
#include <time.h> // 랜덤을 위한 헤더
#pragma warning(disable : 4996) // visual studio 2013 또는 그 이상을 사용하지 않는다면 필요없음

#define NUM 50

int box[NUM];

void SetSock() // 상자 안에 양말 넣기
{
srand((unsigned)time(NULL));
int a = rand() % NUM;
printf("%d\n", a); // 확인용 출력
for (int i = 0; i < NUM; i++)
{
if (i == a)
{
box[i] = 11; // 양말이 있는 상자
}
else
{
box[i] = 10; // 양말이 없는 상자
}
}
}

int BoxSum(int a, int b) // 상자들의 무게의 합
{
int w = 0;
for (int i = a; i < b; i++)
{
w += box[i];
}
return w;
}

void FindSock(int a, int b)
{
int n = b - a; // 개수
int delta = n / 3 + 1; // 한 묶음의 상자 개수

int boxSum1 = BoxSum(a, a + delta);
int boxSum2 = BoxSum(a + delta, a + 2 * delta);

if (n == 1)
{
printf("ans : %d\n", a); // 답 출력
return;
}

if (boxSum1 == boxSum2) // 첫번째 상자들과 두번째 상자들의 무게가 같다면
{
FindSock(a + 2 * delta, b);
return;
}
else if (boxSum1 > boxSum2) // 첫번째 상자들이 무겁다면
{
FindSock(a, a + delta);
return;
}
else // 두번째 상자들이 무겁다면
{
FindSock(a + delta, a + 2 * delta);
return;
}
}

int main()
{
SetSock();
FindSock(0, NUM);
}
Sylphi
그러고보니 제쪽이 문제 자체를 잘못 이해하고 답변했네요. 저경우에는 제가 답변한대로는 결과가 안나옵니다.
(25, 25같이 같은 숫자의 경우에는 차이가 나겠지만, 12, 13같은 경우에는 무게가 121, 130 혹은 120, 131가 나와서 갯수가 적은쪽이 무조건 가벼움)

A BCDe님이 말하신대로 하면 결과가 나올겁니다.

SPOILER
양말이 들어있는 상자가 어느쪽에 있냐에 따라서 아래와 같이 되니

171, 170, 160
170, 171, 160
170, 170, 161

첫번째와 두번째 묶음을 비교해서 같다면 세번째 묶음에 양말이 있는 상자가 있는거고
나머지의 경우에는 더 무게가 많이 나가는쪽이 양말이 있는거라고 보면 되니까요

만약 11번째 상자에 양말이 있다는 전제하에 계산해보면 이런식으로 될겁니다.

17(171), 17(170), 16(160)
6(60), 6(61), 5(51)
3(20), 3(21), 0(30)
1(10), 1(11), 1(10)

도데체 왜 전 상자무게를 1로 보고 양말 무게로 10으로 본걸까요. (본격 상자보다 양말이 더 무거운 이상한 선물)
Kawashiro
결국 제출 못하고 0점 받았지맘 답변 감사합니다

다음엔 꼭 일찍 물어보는걸로....ㅠㅠ
Topic Starter
A BCDe
살아나라 스레드여

그렇다고 아무것도 안 올릴 수는 없으니

quick sort in c++
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

void quick(int left, int right, int* arr)
{
int pivot = left;
int i = left + 1;
int j = right;
if(left < right)
{
while(i <= right)
{
if(arr[i] < arr[pivot])
swap(arr[i], arr[++j]);
i++;
}
swap(arr[left], arr[j]);
pivot = j;
quick(left, pivot - 1, arr);
quick(pivot + 1, right, arr);
}
}
Doyak
ACM-ICPC 예선 아마 탈락인 거 같네요. 89등인데 학교 내 7등이라 여기까지 안 뽑아줄 듯합니다 ㅠㅠ

그러니 백준 열심히 합시다
Topic Starter
A BCDe
아쉽네요 ㅠㅠ

그나저나 여기서 acmicpc를 보니 정말 반갑습니다!

Doyak wrote:

그러니 백준 열심히 합시다
Doyak
문제 난이도가 딱 4문제까지는 쉽거나 평이하고, 그 위로는 갑자기 헬이었던 느낌이네요. 4문제 푼 팀이 150팀 가까이 되는데 한 팀을 제외하곤 모두 푼 문제 종류가 똑같고, 5개 이상 푼 팀들이 추가로 푼 문제들은 제법 다양하게 분포한 걸 보면요. 작년에 7문제 이상 푼 팀 수랑 이번에 6문제 이상 푼 팀 수가 비슷하기도 하고요.
Topic Starter
A BCDe
그래도 J는 그 중에서도 어려웠답니다
이번에는 5문제 이상 풀면 충분히 잘한 팀이죠.
저같은 경우는 팀에서 4문제를 풀고 G를 손댔는데 DP로 접근이 안 되서 시간 다 날렸네요.
(나중에 지인한테 풀이를 들어보니 DP라고는 하던데.)
Doyak
G번 팀원이 2차원 dp로 풀고 있었는데 제출했더니 시간초과가 났다고 하더라고요. 정답은 자신 없어도 시간은 괜찮을 거라고 생각하셨다는데 안타깝던 ㅠㅠ

전 괜히 C번 팠다가 시간만 날렸고, L번이랑 F번도 꽤 들여다봤는데 잘 안 되더라고요.
Taeyang
잘 안풀렷던 문자열 문제 2개만 질문 해보겠습니다.!

문제 1
제가짠 코드
#include <stdio.h>
#include <string.h>

int main() {
char word[50][101];
int i,cnt=0;
while(1){
gets(word[cnt]);
cnt++;
if(word[cnt][0]=='0') break;
}
printf("%d\n",cnt);
for(i=0;i<cnt;i++){
if(i%2==0){
puts(word[i]);
}
}
return 0;
}
이건 if절쪽 if(word[cnt][0]=='0') break; 이놈이 잘못된거 같은데 어떻게 맞게 고쳐야 할지 모르겠음

문제2

 
#include <stdio.h>
#include <string.h>

int main()
{
char st[101];
int i,len;
while(1){
gets(st);

if(st[0]=='E'&&st[1]=='N'&&st[2]=='D') break;

len=strlen(st);
for(i=len;i>=0;i--){
printf("%c",st[i]);
}
}
return 0;
}

이것도 END 입력하면 끝내야하는데 안끝남...
Doyak
1. word[cnt]에 문자열을 입력받았는데 그 즉시 cnt를 증가시켰으니 if문에서 검사되는 word[cnt][0]은 입력받을 때보다 1 큰 cnt로 검사하는 거니, 절대로 걸릴 리가 없죠.

2. 잘 끝나는데요? 그보다 len부터 시작하면 안 되고 len - 1부터 시작해야 원하는 결과를 얻으실 수 있을 거에요. len번째에는 널 문자가 저장되어 있으니까요.
Topic Starter
A BCDe
히익 한발 늦었다

참고로 덧붙이자면 저는 문자열 입력을 받을 때는 scanf나 gets보다 fgets를 '주로' 사용합니다.

아니면 아얘 cin을 쓰거나..
Doyak
C++은 C++14부터 gets 함수 자체를 아예 지원을 안 합니다. 사실, 안전성 부분에 있어서 gets, scanf, strcpy 같이 위험한 함수들은 C에서도 점차 비추하는 추세죠. (VS에서 따로 설정을 안 하면 에러를 띄우는 이유)

그리고 cin이 좋기는 한데 알고리즘 문제에 있어선 scanf보다 느린 게 ㅠㅠ
Topic Starter
A BCDe
cin은 std::ios::sync_with_stdio(false)를 써주면 scanf()보다 더 빠른 성능을 보여줍니다!
Taeyang
1.우왕 cnt 랑 if 있는곳 바꾸니깐 해결됨....
2.
#include <stdio.h>
#include <string.h>

int main()
{
char st[101];
int i,len;
while(1){
scanf("%s",st);
if(st[0]=='E'&&st[1]=='N'&&st[2]=='D'&&st[3]=='\0') break;
len=strlen(st);
for(i=len-1;i>=0;i--){
printf("%c",st[i]);
}
printf("\n");
}
return 0;
}

이랬더니 해결됨 gets()를 쓰면 이상하게 한칸 띄워진 다음에 출력되네영
Taeyang
책이 한 7~8년 된 책이라 그런지... scanf_s은 저기서 먹히지도 않음 ㅠㅠ
이제 포인터랑 파일 입출력 파트만 끝내면 끝난다\o/~

지금 포인터 중간쯤 풀고있는데 이거 어따가 활용하나요 (책에는 안나와있음)
인터넷에 나온 설명 보긴 봤는데
http://blog.naver.com/qorckddls010/220981696090
http://cafe.naver.com/cafec/366826 이런거...
구체적으로 어쩔때 쓰고 활용해야 될질 모르겠습니다.
Doyak
엇 그걸 해도 cin은 scanf보다 느리다고 들었는데 잘못된 정보려나요?
Topic Starter
A BCDe

Doyak wrote:

엇 그걸 해도 cin은 scanf보다 느리다고 들었는데 잘못된 정보려나요?
https://online.acmicpc.org/help/cpp
여기서는 이 방법을 소개하고 있고,
https://stackoverflow.com/questions/1042110/using-scanf-in-c-programs-is-faster-than-using-cin
여기서는 사용 예시를 보여주고 있습니다.

Taeyang wrote:

책이 한 7~8년 된 책이라 그런지... scanf_s은 저기서 먹히지도 않음 ㅠㅠ
visual studio 2013 이상을 사용하신다면 scanf_s를 사용해야겠지만(scanf를 사용하면 에러가 발생합니다), 다른 프로그램에서는 적용되지 않은 것으로 알고 있습니다.
물론 그것도 맨 위에 #pragma warning(disable : 4996)을 붙여주신다면 scanf를 사용할 수는 있지만요.

Taeyang wrote:

지금 포인터 중간쯤 풀고있는데 이거 어따가 활용하나요 (책에는 안나와있음)
처음 배울 때는 정말 불편한 것처럼 보이지만 잘 익힌다면 꽤나 유용한 도구로 쓰입니다.
그런데 솔직히 저도 이것이 어떤 곳에 활용되는지는 잘 모르니 조용히 있겠습니다.
Doyak
cin은 빠르군요. 예전에 똑같은 코드를 sync_with_stdio(false) + cout과 printf로 비교해봤을 때는 printf가 몇배는 빨라서, 그 이후로 아예 iostream을 던지고 cstdio만 썼는데 앞으로는 입력은 cin으로 받는 걸 고려해야겠네요.

그리고 사실 cin의 약점 중 하나가, 여러 개의 값을 저장하기 위해서 그 갯수만큼 호출이 되어야 한다는 것인데, 이것도 약간의 변수가 될 수 있을 듯합니다. 시스템 종류나 입력받는 것이 정수인지 문자인지 등에 따라서도 다를 것 같고요.
Topic Starter
A BCDe
그래도 진짜 속도를 따진다면 getchar가 최고죠 ㅎㅎ
불편해서 안 쓴다 뿐이지..
Sylphi

A BCDe wrote:

그래도 진짜 속도를 따진다면 getchar가 최고죠 ㅎㅎ
불편해서 안 쓴다 뿐이지..

ㅋㅋㅋㅋㅋ 그러고보니 그렇네요
Doyak
BOJ 같이 하실 분 구해요

그룹도 만들면 재미있을 텐데 사람이 있으면...

https://www.acmicpc.net/user/djm03178 입니다.
Topic Starter
A BCDe

Doyak wrote:

BOJ 같이 하실 분 구해요

그룹도 만들면 재미있을 텐데 사람이 있으면...

https://www.acmicpc.net/user/djm03178 입니다.
2/n
Doyak
예전에 그 cin이 느리다고 생각했던 이유 중 하나가... cin.tie(NULL); 을 하지 않은 상태에서 cout와 cin을 번갈아 쓸 경우 cin을 사용할 때마다 cout에 flush가 일어나서 매우 느렸던 일이 있었는데, 이걸 써주니 괜찮네요. 환경마다 다르긴 하겠지만 BOJ에서 정수 입력 기준으론 cin이 scanf보다 확실히 빠르게 나오네요.
Left
#offtopic 이 살며시 떠올라버리는건
Doyak

Left wrote:

#offtopic 이 살며시 떠올라버리는건

그래서 이제 장소를 아예 딴 서버로 옮겼죠
Please sign in to reply.

New reply