본문으로 건너뛰기

· 약 2분
karais89

문제 요약

당신에게는 n개의 일차원 배열이 주어진다.

여기서 k는 (i,j)의 쌍을 나누는 수이다. (단 i < j) k로 나누었을때 나머지가 없는 쌍의 개수를 구해라.

Sample Input

6 3
1 3 2 6 1 2

Sample Output 0

5

설명

  • (0,2) -> 1+2=3
  • (0,5) -> 1+2=3
  • (1,3) -> 3+6=9
  • (2,4) -> 2+1=3
  • (4,5) -> 1+2=3

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static int divisibleSumPairs(int n, int k, int[] ar) {
// Complete this function
int totalCount = 0;
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
if ((ar[i]+ar[j])%k==0)
{
totalCount++;
}
}
}
return totalCount;
}

static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] ar_temp = Console.ReadLine().Split(' ');
int[] ar = Array.ConvertAll(ar_temp,Int32.Parse);
int result = divisibleSumPairs(n, k, ar);
Console.WriteLine(result);
}
}

wanbo의 답안

#include <bits/stdc++.h>
using namespace std;

int n, k;
int a[N];

int main() {
cin >> n >> k;
for(int i = 0; i < n; i++) cin >> a[i];

int res = 0;
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
if((a[i] + a[j]) % k == 0) res++;
cout << res << endl;
return 0;
}

usinha02

문제를 풀면서 혹시 O(n)으로 푸는 방법이 존재하지 않을까 싶었는데, 역시나 존재한다.

using namespace std;
int main(){

int n;
int k;
cin >> n >> k;
int a[n];
int m[k];
for(int i=0; i<k; i++) {
m[i]=0;
}

for(int i = 0; i < n; i++) {
cin >> a[i];
m[a[i]%k]++;
}

int sum=0;
sum+=(m[0]*(m[0]-1))/2;
for(int i=1; i<=k/2 && i!=k-i; i++) {
sum+=m[i]*m[k-i];
}

if(k%2==0) {
sum+=(m[k/2]*(m[k/2]-1))/2;
}

cout<<sum;
return 0;
}

느낀점

그냥 간단하게 이중 for문을 사용하여 구할 수 있다.

· 약 11분
karais89

book image

스프트웨어 개발자 자기 계발서적

기간

2일

목적

ebook으로 구매

도서관에서 한번 봤다가 괜찮은 책인 것 같아서 구매 함.

더 나은 프로그래머가 될 수 있는 방법

"오늘 정말 멋지게 일 했어"라고 스스로 읉조리는 그런 프로그래머라면 이 책은 당신을 위한 책.

리뷰

  • 책의 저자는 브라질 시골 출신의 프로그래밍을 좋아하는 평범한 개발자이다.
  • 프로페셔널리즘/실용주의/자부심에 대한 책
  • 다루는 범위 (디자인패턴, 페어 프로그래밍, 테스트 주도 개발, 빠듯한 일정에 대응하는 방법, 채용 공고 작성법, 개발자 채용 인터뷰, 동료나 관리자와의 협업 방법 등)
  • 프로페셔널로 성장하고 소프트웨어 장인이 되기 위해 필요한 행동 양식, 태도, 조직 구조들에 대한 백과 사전같은 책
  • 일을 어떻게 했느냐는 일을 해낸 것만큼이나 중요하다.

요약

소프트웨어 장인정신이란?

위키피디아에서의 정의

소프트웨어를 개발할 때 개발자 스스로의 코딩 스킬을 강조하는 개념이다. 이러한 개념은 주류 소프트웨어 업계가 개발자의 역량보다는 다른 것들, 즉 예산과 같은 것들을 우선시하는 병폐에 대한 개발자들의 반발로 나타났다.

좀더 주관적인 정의

소프트웨어 장인정신은 마스터가 되어가는 긴 여정이다. 소프트웨어 장인정신은 소프트웨어 개발자가 스스로가 선택한 커리어에 책임감을 가지고, 지속적으로 새로운 도구와 기술을 익히며 발전하겠다는 마음가짐이다. 소프트웨어 장인정신은 책임감, 프로페셔널리즘, 실용주의 그리고 소프트웨어 개발자로서의 자부심을 의미한다.

짧은 정의

소프트웨어 장인정신은 소프트웨어 개발의 프로페셔널리즘에 대한 것이다.

이 문장 만큼은 기억하자.

소프트웨어 매니페스토1

소프트웨어 장인을 열망하는 우리는, 스스로의 기술을 연마하고, 다른 사람들이 기술을 배울 수 있도록 도움으로써 프로페셔널 소프트웨어 개발의 수준을 높인다. 이러한 일을 하는 과정에서 우리는 다음과 같은 가치들을 추구한다. 동작하는 소프트웨어뿐만 아니라, 정교하고 솜씨 있게 만들어진 작품을, 변화에 대응하는 것뿐만 아니라, 계속해서 가치를 더하는 것을, 개별적으 협력하는 것뿐만 아니라, 프로페셔널 커뮤니티를 조성하는 것을, 고객과 협업하는 것뿐만 아니라, 생산적인 동반자 관계를,

내 커리어의 주인은 누구인가

스스로를 발전시키는 데 자신의 돈과 시간을 들여햐 한다.

나 자신의 커리어의 주체로서 언제, 무엇을 배울지를 스스로 결정해야 한다.

끊임없는 자기계발

  • 독서
  • 블로그 (현재 배우는 것이 무엇이든 글로 써서 기록을 남기는 것은 가치가 있다.)
  • 기술 웹사이트

카타

카나는 품세라는 뜻으로 일본 무예 훈련에서 나온 용어다.

소프트웨어 카타는 작은 훈련용 코딩들을 의미한다.

같은 코딩 카타를 반복하더라도 매번 다른 테크닉, 다른 언어, 다른 기술, 다른 접근 방법을 사용해야 효과를 최대화할 수 있다.

  • codingkata.org
  • codekata.pragporg.com
  • kate.softwarecraftsmanship.org

펫 프로젝트

최고의 자가 학습, 자가 훈련 방법은 펫 프로젝트다.

펫 프로젝트는 취미생활과도 비슷한 나만의 소프트웨 프로젝트다.

일정이나 예산 등 압박 요인이 아무것도 없다. 수익을 낼 필요도 없고, 요구사항도 내 마음대로다. 특히 어떤 기술과 방법론을 정욕할 것인지는 내키는 대로 정할 수 있다. 내가 바로 사장이다.

펫 프로젝트는 흥미를 가지고 열정적으로 할 수 있는 주제를 찾으면 된다. 여행을 좋아한다면 여행에 대한 웹사이트를 만들면 되고, 달리기를 좋아한다면 얼마나 많이 달렸는지에대해서 진도를 보여주고 관리해주는 앱을, 일상을 효율적으로 관리하는 데 관심이 많다면 나만의 일정 관리 앱을 만들면 된다.

오픈 소스

오픈 소스 프로젝트에 기여하는 것도 좋은 훈련 방법이다.

작은 것부터 시작하자, 문서에 내용을 추가한다든가, 테스트 코드를 작성한다든가, 버그 목록이나 구현해야 할 기능 목록에서 가장 간단한 것을 선택해 시도해보자,

페어 프로그래밍

기술적인 실행 관례라기보다는 사회적 활동에 더 가깝다.

집중: 뽀모도로 기법

  1. 어떤 일을 할지 정한다.
  2. 뽀모도로(타이머)를 25분에 맞춘다.
  3. 타이머가 끝날 때까지 그 일을 한다.
  4. 짧게 쉰다(보통 5분)
  5. 매 4회의 뽀모도로마다 길게 쉰다(15~20분)

결단과 집중

어디로 가고 있는지 모르고 있다면, 결국 가고 싶지 않은 곳으로 간다.

스프트웨어 장인으로서 스스로의 커리어를 가치있게 여기고 아끼고 보살펴야 한다.

기회를 만들어 내기 위해 할 수 있는 몇 가지 활동들

  • 익숙하고 편한 것에서 벗어나 새로운 것을 공부하고 기술적 지식을 확장한다. 예를들어 새로운 프로그래밍 언어나 기술들을 배운다.
  • 지역 커뮤니티에 정기적으로 출석하거나 행사에 참여한다.
  • 다른 개발자, 비즈니스팬들과 교류한다
  • 새롭게 배운 것, 지금 하고 있는 것들에 대해 블로깅한다.
  • 오픈 소스 프로젝트에 참여한다.
  • 프로젝트를 만들고 공개한다.
  • 콘퍼런스에 참석한다.
  • 콘퍼런스에서 연사로 나선다.

이력서에서 열정 수준을 가늠할 방법

열정 : 자신의 커리어를 위해 개인 시간을 들여서 스스로에게 투자하는 사람.

  • GitHub 계정
  • 블로그
  • 오픈 소스 활동
  • 기술 커뮤니티나 사용자 그룹 활동 내역
  • 펫 프로젝트 내용
  • 트위터 계정
  • 좋아하는 기술서적 목록
  • 참석했거나 발표했던 콘퍼런스

면접에서 관심을 두어야 할 사항

  • 면접관은 누구인가? (프로젝트 관리자? 개발자? 팀 리더? 아키텍트?)
  • 얼마나 많은 지원자들을 면접보고 있나?
  • 원샷 먼접인가 다단계 면접인가?
  • 지원자에게 어떤 종류의 질문들이 주어지고 있나?
  • 특정된 질문인가 개방형 질문인가?
  • 면접관이 기술적 질문에 대해 yes/no 단답형을 좋아하는가, 좀더 상세하게 지원자의 생각들을 파보려 하는가?

바람직한 면접 방법

  • 좋은 면접은 자유 토론과도 같아야 한다. 소프트웨어 개발과 관련하여 지식과 정보를 교환하고, 기술/도구/방법론들에 대해세도 의견을 나누어야 한다.

관련 서적

  • 클린 코드
  • 클린 코더
  • 익스트림 프로그래밍
  • 도제의 형태: 소프트웨어 장인을 장려하기 위한 가이드북
  • 테스트 주도 개발
  • 도메인 기반 개발
  • 실용주의 프로그래머
  • 디자인패턴(GOF)
  • 열정적인 프로그래머

평점 및 한줄평

4 / 5


  1. 개인이나 단체가 대중에 대하여 확고한 정치적 의도와 견해를 밝히는 것으로 연설이나 문서의 형태이다. 종종 비정치적인 분야에서도 자신의 주장과 견해를 분명히 밝히는 때에도 사용된다.

· 약 5분
karais89

개념

유클리드 호제법은 2개의 자연수 또는 정식의 최대공약수를 구하는 알고리즘의 하나이다.

호제법이란 말은 두 수가 서로 상대방 수를 나누어서 결국 원하는 수를 얻는 알고리즘을 나타낸다.

2개의 자연수(또는 정식) a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이 성질에 따라, b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다. 이는 명시적으로 기술된 가장 오래된 알고리즘으로서도 알려져 있으며, 기원전 300년경에 쓰인 유클리드의 《원론》 제7권, 명제 1부터 3까지에 해당한다.

예시

1071과 1029의 최대공약수를 구하면,

  • 1071은 1029로 나누어떨어지지 않기 때문에, 1071을 1029로 나눈 나머지를 구한다. => 42
  • 1029는 42로 나누어떨어지지 않기 때문에, 1029를 42로 나눈 나머지를 구한다. => 21
  • 42는 21로 나누어떨어진다.

따라서, 최대공약수는 21이다.

78696과 19332의 최대공약수를 구하면,

 78696 = 19332×4 + 1368
19332 = 1368×14 + 180
1368 = 180×7 + 108
180 = 108×1 + 72
108 = 72×1 + 36
72 = 36×2

따라서, 최대공약수는 36이다.

소스코드

재귀 호출로 해결 가능

아래 코드는 b가 0이 될때까지 계속해서 재귀 호출을 해주고, 0이 되면 a를 반환한다.

int gcd(int a, int b)
{
/*
* eqaul logic
* if (b==0) return a;
* gcd(b, a%b)
*/
return b ? gcd(b, a%b) : a;
}

재귀 호출은 문제가 생길 수 있는 방법이므로 아래와 같이 변경 할 수 있다.

int gcd(int a, int b)
{
while (b > 0)
{
int tmp = a;
a = b;
b = tmp%b;
}
return a;
}

최소공배수 구하기

최소공배수는 최대공약수와는 반대로, 두 정수가 공통적으로 가지는 배수 중 가장 작은 값을 의미합니다.

최소공배수는 최대공약수와 밀접한 관계가 있는데, 정수 a, b의 최대공약수 G = gcd(a, b)에 대하여 아래의 식을 만족하는 정수 x와 y가 존재합니다.

a = Gx, b = Gy (단, x, y는 정수)

이 때 a b = GGxy 임을 알 수 있고, G는 두 수의 최대 공약수이며 x와 y는 서로소인 관계를 가집니다.

집합적으로 생각하면, a와 b의 합집합은 G, x, y이고 이 세 수를 곱한 Gxy가 최소공배수가 됨을 알 수 있습니다.

  1. a b = GGxy
  2. a b / G = GGxy / G (양변에 최소 공약수를 나누어 줌)
  3. a b / G = Gx*y(최소공배수)
  4. 최소공배수 = a * b / G

그러므로 두 수의 최소공배수 L = lcm(a, b)은 L= lcm(a, b)= a * b / gcd(a, b)이 성립합니다.

최대공약수와 최소공약수 사이의 관계와 유클리드 호제법을 활용해 구할 수도 있습니다.

int lcm(int a, int b)
{
return a * b / gcd(a,b);
}

· 약 6분
karais89

문제 요약

Sample Input

2 3
2 4
16 32 96

Sample Output

3
a = {2,4}

b = {16, 32, 96}

x = 4:
a의 모든 요소는 4로 나누어짐
b의 모든 요소는 4로 나누어짐

x = 8:
a의 모든 요소는 8로 나누어짐
b의 모든 요소는 8로 나누어짐

x = 16:
a의 모든 요소는 16로 나누어짐
b의 모든 요소는 16로 나누어짐

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static int GetTotalX(int[] a, int[] b)
{
// Complete this function
int lcm = GetLCMByArr(a);
int gcd = GetGCDByArr(b);


int totalCount = 0;
for (int i = lcm, j=2; i <= gcd; i=lcm*j, j++)
{
if (gcd % i == 0)
{
totalCount++;
}
}
return totalCount;
}

// GCD = greatest common divisor
static int GetGCD(int a, int b)
{
int gcd = 1;
int minVal = Math.Min(a, b);
for (int i = 2; i <= minVal; i++)
{
if (a % i == 0 && b % i == 0)
{
gcd = i;
}
}
return gcd;
}

// LCM = least common multiple
static int GetLCM(int a, int b)
{
return a * b / GetGCD(a, b);
/*
int lcm = 1;
int maxVal = Math.Max(a, b);
for (int i = maxVal; ;i++)
{
if (i % a == 0 && i % b == 0)
{
lcm = i;
break;
}
}
return lcm;
*/
}

static int GetGCDByArr(int[] arr)
{
int gcd = arr[0];
for (int i = 1; i < arr.Length; i++)
{
gcd = GetGCD(gcd, arr[i]);
}
return gcd;
}

static int GetLCMByArr(int[] arr)
{
int lcm = arr[0];
for (int i = 1; i < arr.Length; i++)
{
lcm = GetLCM(lcm, arr[i]);
}
return lcm;
}

static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int m = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
string[] b_temp = Console.ReadLine().Split(' ');
int[] b = Array.ConvertAll(b_temp,Int32.Parse);
int total = GetTotalX(a, b);
Console.WriteLine(total);
}
}

zemen의 답안

import java.util.*;

public class Solution {
public static int gcd(int a, int b) {
while (a > 0 && b > 0) {

if (a >= b) {
a = a % b;
}
else {
b = b % a;
}
}

return a + b;
}

public static int lcm(int a, int b) {
return (a / gcd(a, b)) * b;
}

public static int getTotalX(int[] a, int[] b) {

int multiple = 0;
for(int i : b) {
multiple = gcd(multiple, i);
}
// System.err.println("Multiple: " + multiple);

int factor = 1;
for(int i : a) {
factor = lcm(factor, i);
if (factor > multiple) {
return 0;
}
}

if (multiple % factor != 0) {
return 0;
}
// System.err.println("Factor: " + factor);

int value = multiple / factor;

int max = Math.max(factor, value);
int totalX = 1;

for (int i = factor; i < multiple; i++) {
if (multiple % i == 0 && i % factor == 0) {
totalX++;
}
}
return totalX;
}

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scan.nextInt();
}
int[] b = new int[m];
for (int i = 0; i < m; i++) {
b[i] = scan.nextInt();
}
scan.close();

int total = getTotalX(a, b);
System.out.println(total);
}
}

t_tashasin의 답안

알고리즘 수행 속도 O(n log(n))의 해결방안:

  1. a 배열의 LCM(최소공배수)을 찾아라.
  2. b 배열의 GCD(최대공약수)를 찾아라.
  3. GCD를 균등하게 나누는 LCM의 배수를 세어라.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[] a = new int[n];
for(int a_i=0; a_i < n; a_i++){
a[a_i] = in.nextInt();
}
int[] b = new int[m];
for(int b_i=0; b_i < m; b_i++){
b[b_i] = in.nextInt();
}

int f = lcm(a);
int l = gcd(b);
int count = 0;
for(int i = f, j =2; i<=l; i=f*j,j++){
if(l%i==0){ count++;}
}
System.out.println(count);
}

private static int gcd(int a, int b) {
while (b > 0) {
int temp = b;
b = a % b; // % is remainder
a = temp;
}
return a;
}

private static int gcd(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = gcd(result, input[i]);
}
return result;
}

private static int lcm(int a, int b) {
return a * (b / gcd(a, b));
}

private static int lcm(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = lcm(result, input[i]);
}
return result;
}

느낀점

먼저 처음에 문제 자체를 이해를 잘 못해서 해맨 상태에서, 최대 공약수 및 최소 공배수를 이용해서 문제를 푸는 것 자체는 파악을 했다.

하지만 다양한 테스트 케이스에서 통과를 하지 못하고, 결국 문제 자체는 힌트를 보고 풀었다.

결국엔 최대 공약수 및 최소 공배수의 알고리즘을 알면 풀 수 있는 문제라고 생각해서 문제를 풀었지만, 테스트 케이스에서 인자가 조금 많아지니, 알고리즘 자체의 성능이 문제가 되어 테스트 케이스에 통과하지 못했다.

최종적으로는 유클리드 호제법을 사용하여 문제를 풀어야 된다.

유클리드 호제법에 대해서는 나중에 한번 다시 한번 정리를 해봐야 될 것 같다.

· 약 4분
karais89

문제 요약

릴리는 초콜렛 n 줄을 가지고 있다.

론의 생일이라 릴리는 자신의 초콜릿 바를 일부분 줄려고 한다.

생일의 월은 m일은 d라고 했을시 m에 연속된 숫자의 합이 d와 일치하는 숫자의 카운터 만큼 줄려고 한다.

Sample Input 0

5
1 2 1 3 2
3 2

Sample Output 0

2

2번 연속해서 나오는 수의 합이 3인 숫자.

1+2=3, 2+1=3 이므로 2개이다.

Sample Input 1

6
1 1 1 1 1 1
3 2

Sample Output 1

0

2번 연속해서 나온 숫자의 합이 6인 것은 없다.

Sample Input 2

1
4
4 1

Sample Output 2

1

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static int solve(int n, int[] s, int d, int m){
// Complete this function
int count = 0;
for (int i = 0; i < n; i++)
{
int sum = 0;

for (int j = i; j < i + m && j < n; j++)
{
sum += s[j];
}

if (sum == d)
{
count++;
}
}
return count;
}

static void Main(String[] args) {
int n = Convert.ToInt32(Console.ReadLine());
string[] s_temp = Console.ReadLine().Split(' ');
int[] s = Array.ConvertAll(s_temp,Int32.Parse);
string[] tokens_d = Console.ReadLine().Split(' ');
int d = Convert.ToInt32(tokens_d[0]);
int m = Convert.ToInt32(tokens_d[1]);
int result = solve(n, s, d, m);
Console.WriteLine(result);
}
}

adititayal9의 답안

import java.util.*;

public class Solution {

public static int getNumberOfWays(int n, int d, int m, int[] sum) {
// Modify array to make each 'i' contain the running sum of prior elements
for (int i = 1; i < n; i++) {
sum[i] += sum[i - 1];
}

// Set number of ways counter
// If there are >= 'm' squares AND the first possible piece has sum = 'd', 1
// Else, 0
int numberOfWays = (m <= n && sum[m - 1] == d) ? 1 : 0;

// Check the sums for pieces ending at index 'm' through 'n - 1'
for (int i = m; i < n; i++) {
// If the sum of the piece is equal to 'd'
if (sum[i] - sum[i - m] == d) {
// Increment ways counter
numberOfWays++;
}
}

return numberOfWays;
}

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] squares = new int[n];
for(int squares_i=0; squares_i < n; squares_i++){
squares[squares_i] = in.nextInt();
}
int d = in.nextInt();
int m = in.nextInt();
in.close();

System.out.println(getNumberOfWays(n, d, m, squares));
}
}

Prince_sai의 답안

int getWays(int n, int* squares, int d, int m){
// Complete this function
int sum[105];
int count=0;
sum[0]=0;
for(int i=0;i<n;i++)sum[i+1]=sum[i]+squares[i];
for(int i=0;i<=n-m;i++){
if(sum[i+m]-sum[i]==d){
count++;
}
}
return count;
}

kcoddington0925의 답안

역시 linq를 사용하면 단 세줄로 문제를 풀 수 있다..

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{

static int getWays(int[] squares, int d, int m)
{
int ways = 0;
for (int i = 0; i < squares.Length - (m - 1); i++)
if (squares.Skip(i).Take(m).Sum() == d) ways++;
return ways;
}

static void Main(String[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] s_temp = Console.ReadLine().Split(' ');
int[] s = Array.ConvertAll(s_temp, Int32.Parse);
string[] tokens_d = Console.ReadLine().Split(' ');
int d = Convert.ToInt32(tokens_d[0]);
int m = Convert.ToInt32(tokens_d[1]);
int result = getWays(s, d, m);
Console.WriteLine(result);
}
}

느낀점

문제 자체를 이해하면 쉽게 풀 수 있는 문제이다.

사실 코딩을 하다 보면, for문 안에 여러개의 조건문을 넣는 경우가 그렇게 많지는 않았던 것 같은데..

일단 내가 짠 코드의 경우 O(n2) 이고 출제자의 경우는 O(n) 인듯 하다.

출제자는 그냥 배열을 이전 합계의 누적 합계가 포함되도록 배열을 수정하고, 거기서 답을 찾는 방식으로 진행 한 것 같다.

· 약 3분
karais89

문제 요약

마리아는 농구를 시즌에 n 게임을 치른다.

마리아는 프로로 뛰고 싶기 때문에, 그녀의 경기가 끝날때 마다 점수를 배열로 순차적으로 매깁니다.

그녀는 시즌 별로 최고 점수를 깬 횟수와 최저 점수를 깬 횟수를 기록 합니다.

첫번째 인자로는 시즌의 총 경기 횟수를 입력 받고, 나머지 인자로는 그 시즌의 점수를 입력 받습니다.

Sample Input 0

9
10 5 20 20 4 5 2 25 1

Sample Output 0

2 4

설명.

그녀는 인덱스 2(20점), 7(25점)에서 최고 점수 기록을 깨고, 인덱스 1(5점), 4(4점), 6(2점), 8(1점) 에서 최저 점수 기록을 깻습니다.

Sample Input 0

10
3 4 21 36 10 28 35 5 24 42

Sample Output 0

4 0

그녀는 최고 기록을 4번이나 세웠고, 시즌에서 첫번째 기록에 비교해서 최악의 점수를 깬 적은 없습니다.

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static int[] getRecord(int[] s){
// Complete this function
int score = s[0];
int bestScore = s[0];
int worstScore = s[0];

int bestCount = 0;
int worstCount = 0;

for (int i = 1; i < s.Length; i++)
{
if (s[i] > bestScore)
{
bestCount++;
bestScore = s[i];
}

if (s[i] < worstScore)
{
worstCount++;
worstScore = s[i];
}
}

return new int[] {bestCount, worstCount};
}

static void Main(String[] args) {
int n = Convert.ToInt32(Console.ReadLine());
string[] s_temp = Console.ReadLine().Split(' ');
int[] s = Array.ConvertAll(s_temp,Int32.Parse);
int[] result = getRecord(s);
Console.WriteLine(String.Join(" ", result));
}
}

StefanK의 답안

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] score = new int[n];
for(int score_i=0; score_i < n; score_i++){
score[score_i] = in.nextInt();
}
int best = 0;
int worst = 0;
int bestCounter = 0;
int worstCounter = 0;
best = score[0];
worst = score[0];
for (int i = 1; i < score.length; i++) {
if (score[i] < worst) {
worst = score[i];
worstCounter++;
}
if (score[i] > best) {
best = score[i];
bestCounter++;
}
}
System.out.println(bestCounter + " " + worstCounter);
}
}

느낀점

확인 해보니 답안과 똑같은 방식으로 풀음.

설명 자체를 하기 곤란한 난이도의 문제 였던 것 같다.

· 약 5분
karais89

문제 요약

두 마리의 캥거루가 있다.

  • 첫 번째 캥거루의 위치는 x1 이고, 캥거루는 v1 만큼 점프해서 이동한다.
  • 두 번째 캥거루의 위치는 X2 이고, 캥커루는 V2 만큼 점프해서 이동한다.

그들이 같은 시간에 같은 장소에 착률 할 수 있으면 YES를 출력하세요.

인풋의 순서는 각각 x1, v1, x2, v2 이다.

Sample Input 0

0 3 4 2

Sample Output 0

YES
  1. 0 -> 3 -> 6 -> 9 -> 12
  2. 4 -> 6 -> 8 -> 10 -> 12

이 캥거리는 4번 점프하면 같은 장소에 만난다.

Sample Input 1

0 2 5 3

Sample Output 1

NO

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static string kangaroo(int x1, int v1, int x2, int v2) {
// first check impossible case : Position is in front and speed is faster
if ((x1 > x2 && v1 > v2) || (x2 > x1 && v2 > v1))
{
return "NO";
}

// backPos and frontPos check
int backPos = 0;
int frontPos = 0;
int backVel = 0;
int frontVel = 0;
if (x1 > x2)
{
backPos = x2;
frontPos = x1;
backVel = v2;
frontVel = v1;
}
else
{
backPos = x1;
frontPos = x2;
backVel = v1;
frontVel = v2;
}

// loop jumping
while (true)
{
backPos += backVel;
frontPos += frontVel;

if (backPos == frontPos)
return "YES";
else if (backPos > frontPos)
return "NO";
}
}

static void Main(String[] args) {
string[] tokens_x1 = Console.ReadLine().Split(' ');
int x1 = Convert.ToInt32(tokens_x1[0]);
int v1 = Convert.ToInt32(tokens_x1[1]);
int x2 = Convert.ToInt32(tokens_x1[2]);
int v2 = Convert.ToInt32(tokens_x1[3]);
string result = kangaroo(x1, v1, x2, v2);
Console.WriteLine(result);
}
}

wanbo의 답안

python으로 문제를 풀었다.

다음 방정식에 해가 존재하는지만 파악 하면된다.

x1 + t v1 == x2 + t v2

이것은 아래와도 같다.

(x2-x1)%(v1-v2) == 0

x1, v1, x2, v2 = map(int, raw_input().split())
X = [x1, v1]
Y = [x2, v2]
back = min(X, Y)
fwd = max(X, Y)
dist = fwd[0] - back[0]

while back[0] < fwd[0]:
back[0] += back[1]
fwd[0] += fwd[1]
if fwd[0] - back[0] >= dist:
break

print ["NO", "YES"][back[0] == fwd[0]]
}

nasimoyz의 (x2-x1)%(v1-v2) == 0에 대한 설명

Input이 0 3 4 2 일때

k1 --- k2
x=0 x=4
v=3 v=2

k1이 도약할때 4에 오는지 확인해야 된다.

v1이 4의 요소인지 여부에 대한 간단한 문제입니다 (명확하게 넘어갈 것입니다).

(x2 - x1) % v1 = (4-0) % 3 = 1

k2가 움직이는 또 다른 경우를 상상해 봅시다 : v2 = 2

v1> v2 인 경우 v1이 결국 따라 잡을 것입니다.

각 점프에서 K1이 3 단계를 진행하고 K2가 2 단계를 진행하면 K1은 각 점프에서 K2를 얻습니다 (각 점프는 점프보다 1 덜 떨어집니다).

이제 K1은 원래 거리 (4)에 가까워집니다.

4 6 8 10 12  <- K2
0 3 6 9 12 <- K1
4 3 2 1 0 <- Difference
1 1 1 1 <- Rate

거리가 닫히는 비율이 그들 사이의 원래 거리까지 합칠 수 있다면 (4), 결국 만나게 될 것입니다.

이제 만나지 않는 예를 들어 보겠습니다. 3 4 10 2

10 12 14 16 18  <- K2
3 7 11 15 19 <- K1
7 5 3 1 -1 <- Difference
2 2 2 2 <- Rate

속도는 원래 거리의 요인이 아니므로 결코 만날 수 없습니다.. 7 % 2 = 1

느낀점

일단 푸는 방식 자체는 비슷한 것 같다.

C# 에서 제공해주는 Min과 Max 함수를 사용했으면 좀더 코드량은 줄어들었을것 같다.

· 약 2분
karais89

Culling(컬링)이란?

카메라에 보이지 않는 부분을 제거하는 작업을 총칭한다.

유니티의 오클루전 컬링이란?

오클루전 컬링은 다른 오브젝트에 가려져 카메라에 비치지 않게 되어 버린 오브젝트의 렌더링을 무효화하는 기능입니다. 3D 컴퓨터 그래픽의 세계에서는 대부분의 경우 카메라에서 먼 오브젝트에서 먼저 그려지며, 더 가까이 있는 오브젝트가 차례차례 덮어써지게 됩니다(“오버 드로우”라고 부릅니다). 오클루전 컬링은 그만큼 당연한 기능이 아닙니다. 오클루전 컬링은 절두체 컬링(Frustum Culling)과는 다릅니다. 절두체 컬링은 카메라의 표시 영역에서 벗어난 오브젝트의 렌더링을 비활성화하는 것이고, 오클루전 컬링과 같이 오버 드로우에 의해 안 보이게 되는 오브젝트 렌더링은 무효화하지 않습니다. 또한,오클루전 컬링을 사용하면서 동시에 절두체 컬링의 혜택을 누릴 수 있습니다.

· 약 4분
karais89

문제 요약

Input 설명

  1. 첫 번째 라인에는 s,t (s와 t는 샘의 집의 범위)
  2. 두 번째 라인에는 a,b (a는 사과위치, b는 오렌지위치)
  3. 세 번째 라인에는 m,n (m은 사과개수, n은 오렌지개수)
  4. 각 사과가 점 a에서 떨어지는 각각의 거리를 나타내는 공백으로 구분 된 정수
  5. 각 오렌지가 점 b에서 떨어지는 각각의 거리를 나타내는 공백으로 구분 된 정수

Output 설명

  1. 샘 집에서 떨어지는 사과 수를 인쇄
  2. 샘 집에서 덜어지는 오렌지 수를 인쇄

샘의 집 주위에 떨어지는 사과와 오렌지 개수를 구하는 문제

Sample Input

7 11
5 15
3 2
-2 2 1
5 -6

Sample Output

1
1
  • 첫번째 사과 위치 : 5-2=3
  • 두번째 사과 위치 : 5+2=7
  • 세번째 사과 위치 : 5+1=6
  • 첫번재 오렌지 위치 : 15+5=20
  • 두번째 오렌지 위치 : 15-6=9
  • 샘의 집 위치는 7~11이고 그 사이에 존재하는 사과 개수는 1개, 오렌지 개수는 1 개이다.

내 소스

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

static void Main(String[] args) {
string[] tokens_s = Console.ReadLine().Split(' ');
int s = Convert.ToInt32(tokens_s[0]);
int t = Convert.ToInt32(tokens_s[1]);
string[] tokens_a = Console.ReadLine().Split(' ');
int a = Convert.ToInt32(tokens_a[0]);
int b = Convert.ToInt32(tokens_a[1]);
string[] tokens_m = Console.ReadLine().Split(' ');
int m = Convert.ToInt32(tokens_m[0]);
int n = Convert.ToInt32(tokens_m[1]);
string[] apple_temp = Console.ReadLine().Split(' ');
int[] apple = Array.ConvertAll(apple_temp,Int32.Parse);
string[] orange_temp = Console.ReadLine().Split(' ');
int[] orange = Array.ConvertAll(orange_temp,Int32.Parse);

int appleSum = 0;
int orangeSum = 0;

for (int i = 0; i < m; i++)
{
int aPos = apple[i] + a;
if (aPos >= s && aPos <= t)
{
appleSum++;
}
}

for (int i = 0; i < n; i++)
{
int oPos = orange[i] + b;
if (oPos >= s && oPos <= t)
{
orangeSum++;
}
}

Console.Write("{0}\n{1}", appleSum, orangeSum);
}
}

vatsalchanana의 답안

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
int s, t, a, b, n, m, d, ans1=0, ans2=0;
cin >> s >> t >> a >> b >> m >> n;

for(int i=0;i<m; i++) {
cin>>d;
d = a+d;
if(d>=s && d<=t)
ans1++;
}
for(int i=0;i<n; i++) {
cin>>d;
d = b+d;
if(d>=s && d<=t)
ans2++;
}
cout << ans1 << endl;
cout << ans2 << endl;
return 0;
}

느낀점

특정 범위 안에 수를 구하는 문제. if문과 && 연산자만 사용하면 풀 수 있는 문제이다. 문제 자체는 어려운게 없다.

문제 자체에 대한 설명이 문제의 난이도에 비해서 좀 길지 않나 싶다.

· 약 3분
karais89

프로세스란?

  • 실행중인 프로그램
  • 주기억장치, CPU의 실행단위
  • 동적인 프로그램
  • 리소스와 스레드의 구성
  • 모든 프로세스는 하나 이상의 스레드를 가짐

스레드란?

  • 경량화된 프로세스
  • 프로세스 내에서 실제 작업을 수행함
  • 한 프로세스 내에서 동작되는 여러 실행의 흐름

스레드 장점

  • 시스템의 자원 소모가 줄어든다. 프로그램의 응답 시간이 단축된다
  • 프로세스 간 통신 방법에 비해 스레드간의 통신 방법이 훨씬 간단하다

스레드의 단점

  • 프로세스 밖에서 스레드 각각을 제어할 수 없다.
  • 여러 개의 스레드를 이용하는 프로그램을 작성하는 경우에는 주의 깊게 설계 해야 한다.
  • 미묘한 시간차나 잘못된 변수를 공유함으로써 오류가 발생할 수 있다.
  • 프로그램의 디버깅이 어렵다. 단일 프로세서 시스템에서는 효과를 기대하기 어렵다.

프로세스와 스레드의 차이점

메모리 사용에 대한 차이

프로세스는 독립적으로 실행됩니다. 자신만의 고유 메모리를 할당 받아서 사용합니다.

스레드는 한 프로세스 내의 여러 흐름으로서 프로세스 내 주소 공간이나 자원을 공유해서 실행합니다.

이러한 특성으로 인해 프로세스 간의 전환보다는 스레드 간의 전환 속도가 더 빠릅니다.