본문 바로가기

카테고리 없음

[javascript] 백준11단계. 정렬 (sort 조건)

백준 테스트 도전!

https://www.acmicpc.net/step

 

단계별로 풀어보기

단계별은 @jh05013님이 관리하고 계십니다. 단계제목설명정보총 문제내가 맞은 문제1입출력과 사칙연산입력, 출력과 사칙연산을 연습해 봅시다. Hello World!132if문if문을 사용해 봅시다.73for문for문을

www.acmicpc.net

위 사이트에서 11단계 정렬에 대해 풀어보자.

 

1) 수 정렬하기(2750번)

   - 문제 : N개의 수가 주어졌을 때, 이를 오름차순으로 한줄에 하나씩 출력하는 프로그램을 작성하시오.

let a=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n')
function solution(n){
    let b=n.slice(1,a.length).sort((a,b)=>a-b).map(Number)
    for(prop of b){
      console.log(prop)
    }
}
solution(a);

2) 수 정렬하기 2(2751번)

   - 문제 : 1번과 동일, 시간복잡도가 O(nlogn)인 정렬 알고리즘으로 풀기... 

      시간 초과로 실패해서 구글링했더니, console.log를 계속 호출해서라고 한다. join으로 합치기

let a=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n')
function solution(n){
    let b=n.slice(1,a.length).sort((a,b)=>a-b).map(Number)
    console.log(b.join('\n'))
}
solution(a);

3) 수 정렬하기 3(10989번)

   - 문제 : node j.s로 풀수없다고 하니 생략


4) 통계학(2108번) 아직 못품

   - 문제 :

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이
let a=require('fs').readFileSync('dev/stdin').toString();
let input=a.trim().split('\n').map(Number).slice(1);
function solution(n){
  let obj={};
  let maxx=[];
  let sum1=Math.round(n.reduce((a,c)=>a+=c)/a.length);
  let sum2=n.sort((a,b)=>a-b)[Math.floor(a.length/2)];
  for(prop of n){
    obj[prop]=prop in obj?obj[prop]+1:1
  }
  let max=Math.max(...Object.values(obj));
  for(prop in obj){
    if(obj[prop]==max) maxx.push(prop)
  }
  maxx=maxx.length>1?maxx.map(Number).sort((a,b)=>a-b)[1]:maxx.map(Number).sort((a,b)=>a-b)[0];
  let sum4=Math.max(...n)-Math.min(...n);
  let total=sum1+'\n'+sum2+'\n'+maxx+'\n'+sum4;
  console.log(total);
}
solution(input);

5) 소트인사이드(1427번)

   - 문제 : 배열을 정렬하는 것은 쉽다. 수가 주어지면, 그 수의 각 자리수를 내림차순으로 정렬해보자.

let input=require('fs').readFileSync('dev/stdin').toString().trim().split('');
function solution(a){
    console.log(a.sort((a,b)=>b-a).join(''))
}
solution(input);

6) 좌표 정렬하기(11650번)

   - 문제 : 2차원 평면 위의 점 N개가 주어진다. 좌표를 x좌표가 증가하는 순으로, x좌표가 같으면 y좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.

let [N, ...input]=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
input=input.map(v=>v.split(' ').map(Number))

function solution(a){
  let k=a.sort((a,b)=>{
    if(a[0]!==b[0]) return a[0]-b[0]
    else return a[1]-b[1]
  })
  console.log(k.map(v=>v.join(' ')).join("\n"))
}
solution(input)
  let k=a.sort((a,b)=>{
    if(a[0]>b[0])  return 1;
    else if(a[0]<b[0])  return -1;
    else return a[1]-b[1];
  }

sort에 조건을 주어 두번 sort가능하다!

sort((a, b) => a[0] - b[0] || a[1] - b[1]); 이렇게 줄여쓸 수도 있다.


7) 좌표 정렬하기 2(11651번)

   - 문제 : 2차원 평면 위의 점 N개가 주어진다. 좌표를 y좌표가 증가하는 순으로, y좌표가 같으면 x좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.

let [N, ...input]=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
input=input.map(v=>v.split(' ').map(Number))
function solution(a){
  let k=a.sort((a,b)=>{
    if(a[1]==b[1]) return a[0]-b[0] //y값이 같으면 x축오름차순대로
    else return a[1]-b[1]
  })
  console.log(k.map(v=>v.join(' ')).join("\n"))
}
solution(input)

8) 단어 정렬 (1181번)

   - 문제 : 알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.

  1. 길이가 짧은 것부터
  2. 길이가 같으면 사전 순으로
let [N, ...input]=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
function solution(a){
  let k=[...new Set(a)].sort((a,b)=>{
    if(a.length>b.length) return 1 
    else if (a.length<b.length) return -1
    else {
      if(a>b) return 1
      else return -1
    }
  })
  console.log(k.join('\n'))
}
solution(input)


  let k=[...new Set(a)].sort((a,b)=>{
    if(a.length>b.length) return 1;
    else if(a.length<b.length) return -1;
    else return a-b
  })

.sort((a, b) => a.length - b.length || a.localeCompare(b)) 이렇게 줄여쓸 수도 있다.


9) 나이순 정렬(10814번)

   - 문제 : 온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을 작성하시오.

let [N, ...input]=require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
input=input.map(v=>v.split(' '))
function solution(a){
  let k=a.sort((a,b)=>a[0]-b[0])
  console.log(k.map(v=>v.join(' ')).join("\n"))
}
solution(input)

//input.sort((a, b) => a.split(" ")[0] - b.split(" ")[0]); 간단히 표현가능

10) 좌표 압축(18870번)

   - 문제 : 수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다.

Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다.

X1, X2, ..., XN에 좌표 압축을 적용한 결과 X'1, X'2, ..., X'N를 출력해보자.

let input=require('fs').readFileSync('dev/stdin').toString().trim().split('\n')[1];
  let a=input.split(' ').map(Number)
  let asort=[...new Set(a)].sort((a,b)=>a-b);
  let obj={};
  let answer='';
  asort.forEach(v=>obj[v]=asort.indexOf(v))
  
  a.forEach(v=>{
    answer+=obj[v]+' '
  })
  console.log(answer)
 //시간초과
let input=require('fs').readFileSync('dev/stdin').toString().trim().split('\n')[1];
function solution(a){
a=a.split(' ').map(Number)
let asort=[...new Set(a)].sort((a,b)=>a-b)
  let answer=[];
  let map=new Map();
  asort.forEach(v=>{
    map.set(v, asort.indexOf(v))
  })
  a.forEach(v=>{
    answer.push(map.get(v))
  })
  console.log(answer.join(' '))
}
solution(input)  //시간초과

후....계속 시간초과여서 구글링하다가 indexOf가 문제엿다고 생각하고 asort.indexOf(v) => index로 고쳤다. 어차피 크게상관없을 거라 생각했는데 직접 index받아서 할당하는거랑, ssort내에 v를 또 찾아서 index를 할당하는거는 어마어마한 차이가 있나보다

let input=require('fs').readFileSync('dev/stdin').toString().trim().split('\n');
function solution(input){
  [n,a]=input;
  a=a.split(' ').map(v=>Number(v))
  let asort=[...new Set(a)].sort((a,b)=>a-b);
  let obj={};
  let answer=[];
  asort.forEach((v,i)=>obj[v]=i)
  
  a.forEach(v=>answer.push(obj[v]))
  return answer.join(' ')
}
console.log(solution(input))

최종정답 ! 시간초과한 위의 1,2번 답도 index부분을 바꿔주니 해결했다 😂