1. O(N^2)  


 C[n][k] = C[n-1][k-1] + C[n-1][k] 


로 다이나믹 프로그래밍 합시다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <cstdio>
int dp[20][20];
int main(void){
    int n, m, k;
    scanf("%d%d"&n, &m);
    for (int i = 0; i <= n; i++)
    {
        dp[i][i] = 1;
        dp[i][0= 1;
    }
    for (int i = 2; i <= n; i++)
        for (int j = 1; j < i; j++)
            dp[i][j] = dp[i - 1][j - 1+ dp[i - 1][j];
    printf("%d",dp[n][m]);
}
cs


2. O(NlogP) 

페르마의 소정리를 알아야 하는데

즉, 

임. 증명은 http://freshrimpsushi.tistory.com/121 참고

ap2를 구하면 되는데, 이는 분할정복으로 log (p-2)만에 구할 수 있음.

소스는 아래 참고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
#define MOD 1000000007
int f[4000010];
int inv[4000010];
int mpow(int n, int p){
    if (p == 1return n;
    int ret = mpow(n, p / 2);
    ret = (long long)ret * ret % MOD;
    if (p % 2) ret = (long long)n * ret % MOD;
    return ret;
}
void make_com(){
    inv[0= inv[1= f[0= f[1= 1;
    for (int i = 2; i <= 4000000; i++){
        f[i] = (long long)f[i - 1* i % MOD;
    }
    for (int i = 2; i <= 4000000; i++){
        inv[i] = (long long)inv[i - 1* mpow(i, MOD - 2) % MOD;
    }
}
int C(int n, int r){
    return (long long)f[n] * inv[r] % MOD * inv[n - r] % MOD;
}
cs


참고로, n^p을 분할정복 하는 것은 여러 곳에서 많이 사용하는 로직임. 알아두면 도움이 될 것 


3. O(N)

쿠사가님의 블로그에서 봤는데, 솔직히 이해가 안가서 직접해 봄. 그랬더니 되더라...  코드 굉장히 짧음. 원본은 탑코더라고 합니다.

http://apps.topcoder.com/forums/?module=Thread&threadID=680416&start=15&mc=26 참고 

증명과 코드는 아래

inv(1) = 1
inv(i) = -(p / i) * inv(p % i)

증명은 아래와 같음

5) 
p mod p는 0임 따라서 없어짐.(p mod p * (1/(i*(p%i)))) mod p 를 분리한다고 생각하면 앞이 0이므로 뒤를 계산할 필요 없이 0임 멍청...) 
 분자 * (1/분모)로 분리한 후 각각 mod 붙인 것

6)  -floor(p/i) 는 p보다 작은 정수이므로 mod p 빼두 됨
inv(i) = -(p / i) * inv(p % i)
해서 이렇게 나옴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
#include <algorithm>
#define MOD 1000000007
#define SIZE 4000000
int f[SIZE +1];
int inv[SIZE+1 ];
void make_com(){
    inv[0= inv[1= f[0= f[1= 1;
    for (int i = 2; i <=SIZE ; i++)f[i] = 1LL*f[i - 1* i % MOD;
    for (int i = 2; i <= SIZE ; i++)inv[i] = -1LL * (MOD / i) * inv[MOD % i] % MOD;
    for (int i = 2; i <= SIZE ; i++)inv[i] = 1LL * inv[i - 1* ((inv[i] + MOD) % MOD) % MOD;
}
int C(int n, int r){return (long long)f[n] * inv[r] % MOD * inv[n - r] % MOD;}
int main(void){
    make_com();
    int a, b;
    scanf("%d%d"&a, &b);
    printf("%d", C(a, b));
}
cs

이게 입사테스트에 나왔다는 이야기를 듣고... 정리합니다.


이해 안가는 부분은 덧글로


문제 참고

https://www.acmicpc.net/problem/11401

https://www.acmicpc.net/problem/11050

다운로드 : https://www.iterm2.com/

스킨 적용 : https://beomi.github.io/2017/07/07/Beautify-ZSH/


zsh 몇가지 편의 기능 추가

prompt_context => 유저 이름 포맷 변경

prompt_dir => file depth를 최대 3까지 출력(너무길어지면 불편해서...)

1
2
3
4
5
6
7
8
prompt_context() {
  if [[ "$USER" != "$DEFAULT_USER" || -"$SSH_CLIENT" ]]; then
    prompt_segment black default "%(!.%{%F{yellow}%}.)$USER"
  fi
}
prompt_dir() {
  prompt_segment blue black "%3~"
}
cs


 단축키

 설명

 cmd + N

새로운 창 생성 

cmd + t 

새로운 탭 새성 

 cmd + d

창 새로 분할 

 cmd + shift + d

창 가로 분할 

cmd + w 

창 종료 

cmd + 숫자

탭 이동 

cmd + [ 

이전 창으로 이동(분할시) 

cmd + ] 

다음 창으로 이동(분할시) 




히스토리 prefix를 방향키로 조절하기


~/.inputrc 에 아래를 입력하고 저장 ( 적용되려면 iterms 껏다 켜라 )

1
2
 "\e[5~": history-search-backward
 "\e[6~": history-search-forward
cs




'개발 > 잡다한팁' 카테고리의 다른 글

git 과거 commit의 이름과 이메일 변경하기  (2) 2021.03.31

OSI 참고 모델


OSI 7계층은 데이터를 송수신하기 위한 규칙이다. 다시말해 프로토콜인데, 이는 데이터의 송수신을 하기 위한 규칙을 표준화 시키기 위해 ISO에서 선언한 것이다.


OSI는 데이터 통신의 단계구성도로 Open Systems interconnection Reference Model의 약자로, 데이터 통신을 7단계로 나누어서 프로토콜들을 관리한다. 이 때 각각의 계층(Layer)들은 서로 독립되어 있다는 것이 중요하다. 이 각각의 계층들은 단계 마다의 복수의 프로토콜로 실현된다. 여기서 독립되어 있다는 것은 어떤 계층의 프로토콜 변경은 다른 계층에 영향을 끼치지 않는다는 것이다. 


일반적으로  OSI  참조 모델은 송신 측은 7계측에서 1계층의 순서로, 수신측에서는 1계층에서 7계층의 순서대로 수행한다.


이 때, 각각의 계층에서 원래의 데이터 이외에도 필요로하는 추가적인 데이터(예컨데, 어디로 도착해야하는지-IP와 같은-같은 것들)를 붙일 필요성이 있는데, 이렇게 필요한 데이터를 붙여서 만든 새로운 데이터를 프로토콜 데이터 유닛, 즉 PDU(Protocol Data Unit)라고 부른다.



이 때, 각각의 계층별 PDU를 따로부르는 이름이 있는데, 5~7계층은 메세지(Message), 4계층은 세그먼트 혹은 데이터 그램, 3계층의 PDU는 데이터그램 혹은 패킷, 2계층은 프레임 1계층은 신호라고 부른다. 


이때 3~7계층의 데이터는 대체로 모두 앞부분에 추가적인 정보가 붙는데 이를 헤더라고 부르고, 2계층에는 앞부분과 뒷부분 모두에 추가적인 데이터가 붙는데 앞부분은 헤더, 뒷부분은 trailer라고 부른다. 이러한 각 계층별 추가로 붙는 정보는 TCP 헤더, 4계층 헤더 라는 식으로 부르기도 한다.


하지만 이러한  계층 사이에서도 상하를 연결할 필요성이 있다. 완전히 제각각이라면 처리가 불가능하기 때문이다. 따라서 이렇게 처리하기 위해 상하 계층 구조간 연결하는 역할을 하는 것이 인터페이스인데, 이렇게 7계층부터 1계층까지 연결된 프로토콜 그룹을 프로토콜 군(Protocol Suite)이라고 부른다. 즉, 데이터 통신은 같은 프로토콜 군을 사용하는 컴퓨터나 기기끼리만 가능한 것이다. 


현재 OSI표준 프로토콜군은 사실상 실패하여 표준화 시키지 못했다. 현실적으로 가장 많이 사용되는 것은 TCP/IP프로토콜군으로 현재 인터넷에서 사용되는 프로토콜군이다. TCP/IP는 사설 표준(De Facto Standard)이다. 사설 표준이란 제정된 프로토콜이 아니라, 사용하는 기기 및 컴퓨터가 압도적으로 많아서 표준 처럼 사용할 수 있게 된 상태가 된 것을 말하는 것이다.


TCP/IP 모델


이 TCP/IP는 IETF(the internet Enginerring Task Force) 라는 단체가 제정한 프로토콜 군으로, 국제 인터넷 표준화 기구라고 부른다. 여기에서 제정하는 문서는 RFC(Request For Comments)라고 불리는데 이것이 규격이 되어 TCP/IP모델의 베이스가 됐다. 



사실상 TCP/IP 모델이 위와 같이 OSI참조 모델과 1:1로 대응 되는 것은 아니다. 이는 데이터 전송 프로토콜군으로서 비교를 하는 것이라 유사한 특징들이 있을 뿐이다. 자세히 들여다 볼 경우에는 차이점 이있다.


TCP/IP프로토콜군의 프로토콜들


4계층(애플리케이션 계층) : HTTP, FTP, SMTP등

3계층(트랜스포트계층): TCP, UDP

2계층(인터넷 계층): IP, ARP

의미상으로는 Point to Point 네트워크는 두개의 단말은 1:1로 연결한 형태를, 멀티 액세스 네트워크는 허브를 이용하여 여러개의 단말을 연결하는 형태로 구성한 네트워크라고 보면 된다. 이 때, 멀티 액세스 네트워크 구조를 가지는 네트워크 형태에서 패킷 교환없이 케이블 분배기로 연결되는 범위를 세그먼트(Segment)라고 부르는데, 이 세그먼트 범위 내에 있는 컴퓨터는 패킷 교환 없이 데이터를 송수신 할 수 있다.




참고 : 하루 3분 네트워크 교실

'Computer Science > 네트워크' 카테고리의 다른 글

OSI 참고 모델과 TCP/IP 프로토콜  (1) 2018.01.23
회선 교환과 패킷 교환  (0) 2018.01.23


어떤 PC와 PC사이에서 통신이 발생하기 위해서는 PC와 PC사이를 이어주는 파이프를 필요로한다. 두개의 PC를 연결하는데는 1가지의 파이프만 필요로 하지만, 만약 3개의 PC를 연결하게 될 경우는 어떨까? 그렇다면 A-B, A-C, B-C를 연결하는 파이프가필요하다. 즉 N개의 PC를 연결하려면 N(N-1)/2개의 파이프를 필요로한다. 이런식으로 연결하는 방식은 이렇게 매우 비효율적이다.


회선 교환 방식


이를 해결하기 위해서 회선 교환방식이 나타났다. 전화해서 이런 방식을 채택하고 있는데, 중간에 어떤 교환기가 있어서 변경해주는 방식을 말한다. 주로 전화기에서 자주 사용한다. 이 회선교환 방식은 교환기와 교환기 사이의 회선 숫자에 따라 한꺼번에 연결 가능한 통화의 개수가 제한되게 된다. 



회선 교환의 문제점 사진 참고(그림4-2)



패킷 교환 방식


이 회선 교환의 문제점을 해결 할 수 있는 대안 중 하나로 패킷 교환이라는 방식이 있다. 


패킷 교환은 데이터를 한꺼번에 한쌍의 연결이 점유하는 방식이 아니라, 데이터를 잘게 쪼개서 보내는 방식이다. 따라서, 회선이 하나 뿐이라고 하더라도 하나의 연결이 회선을 점유하지 않기 때문에 효율적으로 데이터를 송수신 할 수 있다. 이 통신 방식은 인터넷등에서 많이 사용한다. 여기서 패킷교환기는 라우터라는 다른 이름으로 불린다.




참고 : 하루 3분 네트워크 교실

아마존 서비스를 이용하는데에는 총 3가지 방법이 있다.


aws Console                AWS CLI            AWS SDK


콘솔은 웹에서 사용하는 것이고, CLI는 말그대로 aws용 command Line Interface이다.  aws sdk는 각종 프로그래밍 언어등에서 aws를 제어할 수 있도록 제공하는 sdk이다. 뭐, 결국은 모든 것은 aws의 api에 의해서 제어된다. 


aws Console의 경우 사용하기 쉽지만, 제어나 자동화하기에는 한계가 있기 때문에, aws sdk를 통해서 시스템 구축을 자동화 하는것이 맘 편할 것이다.(난이도는 더 높다..)


https://play.google.com/store/apps/details?id=com.amazon.aws.console.mobile

위처럼 모바일 콘솔도 있다 ^ㅇ^


위와 같은 서비스를 사용하기 위해서는 사용자는 자신이 누구인지 인증을 해야하는데, 이를 위해서 사용하는것이 IAM이다. IAM은 aws 계정과 관련된 권한을 제어하고, 관리기능을 제공한다. 



IAM 객체는 두가지 영역으로 구성되는데, 사용자를 정의하는 단위인 IAM User, IAM Group, IAM Role영역이고, 다른 하나는 권한을 정의하는 IAM Policy 영역이다. 


aws 계정을 생성하게 되면, 이 계정은 루트 계정이 된다. 


한 회사에서 관리하는 리소스를 여러 계정에 배치해놓고 쓰기에는 과금도 그렇고 여러므로 불편함으로, 일반적으로 이 루트계정이 권한을 나눈 새로운 유저를 만들어 회사내의 사람에게 분배하는 방식으로 관리를 하게된다. 각각의 사용자에게 직무에 맞는 IAM Policy를 부여함으로서 Human Error를 줄이고, 보안 위협을 사전에 방지한다. 



IAM User


 IAM User는 사용자로서, 여러개의 권한을 할당 받을 수 있고, 또한 IAM GROUP에 속할 수 있다. 유저는 말 그대로 유저로서, 루트에게 받은 권한을 사용할 수 있다. IAM User의 경우에는 aws management console의 로그인 용으로 사용하는 username/password방식을 설정할 수 있고, 또한 accessKey/SecretKey를 설정할 수 있다. 필요에 따라 선택해서 사용하면 된다.


 IAM Group

 IAM Group은 Policy를 미리 설정해두고, User를 넣다 뺐다 할 수 있다. 활용 용도로는 각 부서별로 필요로하는 공통된 권한이 있다면, 해당 부서 명으로 그룹을 만들어서 부서원들의 IAM User를 group안에 넣어주면 되시겠다. (여러개의 유저마다 권한을 설정하기 귀찮으니까)


IAM Role

 IAM Role는 시간부로 권한을 부여한 '역할'로 시간이 지나면 만료 된다. 작동 방식은 어떤 Trusted Entities(주로 아마존 서비스들)가 STS에 임시키를 요청해서 임시키를 발급 받고, 발급받은 임시키로 aws api를 사용한다. 이 키들은 주기적으로 만료되기 때문에, 영구히 유지되는 IAM User에 비해서 보안성이 높다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "Version""2012-10-17",
  "Statement": [
    {
      "Sid""FirstStatement",
      "Effect""Allow",
      "Action": ["iam:ChangePassword"],
      "Resource""*"
    },
    {
      "Sid""SecondStatement",
      "Effect""Allow",
      "Action""s3:ListAllMyBuckets",
      "Resource""*"
    },
    {
      "Sid""ThirdStatement",
      "Effect""Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::confidential-data",
        "arn:aws:s3:::confidential-data/*"
      ],
      "Condition": {"Bool": {"aws:MultiFactorAuthPresent""true"}}
    }
  ]
}
cs



 일반 정책 구조


Policy 문법이다.


Sid는 정책에 관한 설명(아이디)

Effect는 Allow(허가)/Deny(거부) 둘 중 하나를 선택하게된다 거부는 허가보다 우선된다. 

Principal은 API Access가 가능한 계정, 또는 ARN을 서술한다

Action은 사용 가능한 API들의 리스트들이다. 

Resource 는 API 타겟이 될 리소스이다. 마찬가지로 ARN으로 서술한다

Condition은 세부 설정 조건이다.




arn은 aws는 Amazon Resource Name의 약자로, 이름 그대로 리소스의 이름을 뜻하는데, 아마존에서 사용가능한 리소스들은 저마다 구분할 수 있는 arn을 가지고 있다. 


'개발 > AWS' 카테고리의 다른 글

공짜로 서비스 배포하기 Lambda로 서비스 배포하기 (1)  (0) 2023.02.05
aws 시작하기  (0) 2017.08.17
aws에서 결제 알람 받기  (0) 2017.01.23
AWS 준비하기  (0) 2016.10.23

aws는 정말 많은 서비스를 제공하고 있는데, 그냥 개발하다보면, 마치 일반적인 호스팅 업체에서 제공하는 것과 같은 기능 밖에 사용하지 못한다.


aws를 알면 알수록, 보안적으로 안전해지고, 일단 생산성이 올라가게 된다.


그래서 aws를 공부하면서 간단히 포스팅을 해보려 한다.


aws를 쓰면 좋은 점

1. 기존의 서비스를 커버할 수 있는 많은 양의 서비스를 제공한다. 

일반적으로 사용하는 EC2를 비롯해서 database에 관련된 것들이나 , storage서비스등을 it인프라를 구축하지 않고(혹은 가상으로 간단히 구축하고) 돈으로 땜빵할 수 있다.(구축하는데도 돈이들자나!)


2. 탄력적이다. 

서비스의 인프라 규모는 초기에 사업을 시작하기전에 수요를 쉽게 예측하기 어려운데, 이에 맞춘 인프라 규모를 생각할 필요가없다. 사용자가 많으면, 그 만큼 과금되는 시스템이라 그렇다.


3. 자동화가 가능하다. 

aws의 api를 사용하면 서비스를 올리는 바닥부터(심지어 서버를 올리는 것이나, 네트워크 계층을 건드리는 것 까지) 서비스까지 자동화가 가능하다.

물론 드럽게 어렵다. 나같은 초짜에겐...

 

aws의 주요 서비스


aws는 크게 4가지의 코어 서비스를 제공하는데 

compute영역

EC2, ECR, ECS, AWS LAMBDA, ELASTIC LOAD BALANCING

EC2와 같은 가상 서버 서비스이고, lambda는 서버 구성없이 이벤트에 응당하는 코드를 실행해주는 친구다. 다른 친구들은 사용하지 않아서 잘 모르겠다.


storage영역

CloudFront, EFS, Glacier, S3, Import/Export Snowball, Storage Gateway

S3는 AWS에서 제공하는 고가용성/고내구성의 객체 스토리지서비스로 객체를 무제한으로 저장할수 있는 서비스다. 굉장히 유용하고, 가장 유명한 스토리지 서비스인 것 같다. 나머지는 잘모른다. 


database영역

DynamoDB, ElastiCache, RDS, Redshift

이중에서 RDS는 Relational Database Service의 약자로, 관계형 데이터 베이스관련 서비스이다. 아는 왠만한 rds는 다 들어가있다. 

DYNAMODB는 NoSQL db 서비스이다. ElastiCache는 Redis/Memcache같은 인메모리 데이터 베이스를 관리하는 서비스이다.


networking영역

VPC, Route53, Direct Connect

VPC(Virtual Private Cloud)는 사설 IP주소 값을 기반으로 사용자가 구성한 네트워크 영역 위에 EC2와 같은 가상 서버를 배치할 수 있도록 aws에서 제공하는 네트워크 서비다. 



보통, 서비스를 구성하는데 있어서, 이 4가지 영역에 걸쳐서 대부분의 서비스를 사용하게 된다... (그리고 각각 이용하는데마다 요금이 발생하는데, 그래서 어느정도 요금이 나올지 예상하기가 쉽지 않다 ㅠ)


AWS 물리 인프라(Region, AZ, Edge)


aws는 물리 인프라 단위를 Region, AZ, Edge 세가지로 분류하고 있는데, 

AZ는 Availability Zone의 약자로 흔히 데이터 센터라고 보면 된다. 각 AZ는 물리적으로 완전히 독립된 객체이다. 


Region은 두 개 이상의 AZ로 구성되어 있는 동일 지역의 집합체라고 정의 할 수 있는데, 우리가  한국에서 서비스를 하고자한다면 가장 가까운 Seoul Region을 선택하는게 여러므로 유리할 것이다. Region 별로 각 서비스의 가격이 다르며, 서비스도 제공이 되는 것, 안되는 것이 있다. 


세번째 단위는 Edge로 잘 모르겠다. 


aws과금 방식


aws에는 엄청나게 다양한 과금 요소가 있지만 대표적인 과금 요소는 3가지로, Compute, Storage, Data Transfer이다. 이것도, 어떤 서비스를 사용하는지에 따라서 과금 방식이 차이가 나지만, Compute의 경우에는 기본적으로 인스턴스를 유지하는 시간당 비용이 발생한다. 여기서 유지하는 시간이란 해당 인스턴스가 실행되고 있는 시간을 뜻한다.(컴터켜졌으면 돈내라는 것) storage는 용량에 따라 과금하고, Data Transer의 경우 전송량에 비례해 과금이 발생한다.


대부분의 요금들이 On Demand이고, 사용량이 늘어나면 늘어날수록 더 낮은 단가에 제공한다. 또한, 약정을 통해서 과금량을 더 줄일 수도 있다



'개발 > AWS' 카테고리의 다른 글

공짜로 서비스 배포하기 Lambda로 서비스 배포하기 (1)  (0) 2023.02.05
aws IAM  (0) 2017.08.17
aws에서 결제 알람 받기  (0) 2017.01.23
AWS 준비하기  (0) 2016.10.23

문제를 만들다보면 테스트 케이스 제너레이터가 필요하다 뭐 단순 배열이나 랜덤 숫자를 찍는건 간단한 일이지만...


그래프나 트리의 경우는 좀 화가난다. 특정 조건을 만족시키는 그래프를 생성하는게 굉장히 성가진 일이기 때문... 


이런 일을 조금 더 편하게 해주는 사이트가 있는데 그래프나 트리의 일반적인 형태의 경우는 이걸로 만들면 조금 편할 것 같다.


http://spojtoolkit.com/TestCaseGenerator/


몇가지 추가되었으면 하는 것도 있지만...


일단 이정두면 쓸만은 하지않나 싶다



====================


일단 테스트케이스를 어떻게든 만들고 나면 테스트 케이스에 해당하는 아웃풋을 만들어야하는데


소스 코드를 일일이 컴파일 붙여넣기 하거나 소스코드에 하드코딩하는 방법을 주로 사용한다. 그런데 C++은 문자열 관련 연산이 영 귀찮기 때문에 파일 이름 만들고


이런저런 짓을 하는게 좀 귀찮아서...


쉘 스크립트를 좀 짜봤다.


제너럴 하지는 않고 내가 필요한 정도만 짜놨기 때문에 실제 사용하려면 약간의 커스터 마이징이 필요할 지 모르겠다.


난 이걸로 잘 돌려 막기했다.. ㅋㅋㅋㅋㅋㅋㅋ


https://gist.github.com/choiking10/28a3dbe456203c3f92bbd05749377b36



시작한지 얼마나 됐다고 중지하냐고 하면... 할말이없는데


일단 개발 쪽 공부할 여건이 안될 것같아서... 


급하게 필요로하는 프레임워크쪽 먼저 공부를 해야할 것 같네요


일단 영어도 있구요.


ㅎㅇㅅ...

'web > spring' 카테고리의 다른 글

[토비 vol1] 4.1~4.3 예외  (0) 2017.07.26
[토비 vol1] 3.5~3.7 템플릿(2)  (0) 2017.07.26
[토비 vol1] 3.1~3.4 템플릿(1)  (0) 2017.07.26
[토비 vol1] 2.4~2.6 테스트(2)  (0) 2017.07.25
[토비 vol1] 2.1~2.3 테스트(1)  (0) 2017.07.25

자바는... 느리다.

그런데 생각보다 빠르다. 



일반적으로 알고리즘을 풀 때, 자바의 경우는 scanner를 자주 사용한다. 아무래도 여러가지 부가기능이 붙어있으므로 사용하기 편한면 때문에 다들 많이 사용하는 것 같다.


다만, 자바의 경우 입력이 많을 때 , scanner를 써서 시간초과가 날 수 있다. 뿐만 아니라 그때 그때 출력할 경우에도 시간 초과가 날 수 있다.


오늘의 완죤 쉬운 문제 하나를 소개하겠다. 


이름하야 수 정렬하기3  https://www.acmicpc.net/problem/10989


솔루션은 간단한데, 직접 정렬을 할 경우 시간초과에 걸리게 된다. N 사이즈가 천만이기 때문에, log조차 붙이는게 조심스럽다.


그런데 보면 최대 값이 10000이다 따라서 카운팅소트를 진행하시면 되겠다.


근데 이문제의 핵심은 이거라기보다... 


인풋을 얼마나 빨리 받을 수 있냐에 있다. 


자바용 쓸만한 빠른속도로 입력받기 소스를 소개하겠다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class Main {
    public static void main(String[] args) throws IOException{
 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
 
        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[10010];
 
        for (int i = 0; i< N;i++){
            arr[Integer.parseInt(br.readLine())]++;
        }
 
        for(int i =0; i<= 10000; i++){
            while(arr[i] != 0){
                sb.append(""+i+"\n");
                arr[i]--;
            }
            
        }
        System.out.println(sb.toString());
    }
 
}
 
cs

한꺼번에 모아서 입력을 받고 한꺼번에 모아서 출력한다. 라는 쉬운 개념인데, c++의 scanf, printf 보다 성능이 좋다.

이런 쉬운 것에 불필요한 설명을 덧붙이는 것은 좀 귀찮으니... 다들 소스코드 이해하는데 문제 없으리라 보고 이정도만 포스팅 하도록 하겠다.

다만 주의할 것이 StringBuilder를 사용하지 않고 string간의 +연산을 사용할 경우, 

자바를 아시는 분들은 아실 수도 있지만, 당연히 시간 초과가 난다. String간 + 연산에 관해서는 검색해서 찾아보시길 바랍니다. 



+ Recent posts