핵심
주의 사항
키워드
pro() 부분은 기계적, determination 부분 변형 중요
```java
static void determination(int D){
// TODO : 매개변수 변환 문제 해결
}
static void pro(){
// TODO : 기계적 양식임
Arrays.sort(A,1,N+1);
while(L <= R){
int mid = (L + R) /2 ;
if(determination(mid)){
ans = mid; // ans 업데이트
L = mid + 1; // 정확한 ans를 찾기위한 범위 좁히기
}else{
R = mid - 1;
}
}
```
나무 갯수 N , 필요한 나무 길이 M
정답의 최대치
- N = 100만, M = 20억 정답 범위 0 ~ 10억 → int
but, 계산 과정중, 잘린 나무의 길이 합 ≤ 나무 높이의 총합 =10^15 → long
import java.util.Scanner;
public class BOJ_2805 {
static intN,M;
static int[]arr;
static Scannersc= new Scanner(System.in);
static StringBuilderstringBuilder= new StringBuilder();
static void input() {
N=sc.nextInt();
M=sc.nextInt();
arr= new int[N+1];
for (int i = 1; i <=N; i++) {
arr[i] =sc.nextInt();
}
}
static boolean determination(int H) {
// H 높이로 나무를 잘랐을 때 M만큼 얻을 수 있으면 true, 없으면 false
// 자른 나무의 총 길이 합 long 이여야함
long sum = 0;
for (int i = 1; i <=N; i++) {
if (arr[i] > H) {
sum +=arr[i] - H;
}
}
return sum >=M; // M 이상 얻을 수 있으면 true
}
static void pro() {
long L = 0, R = 2000000000, ans = 0;
//[L .. R]사이에 정답 존재한다
//TODO :이분 탐색과 determination문제를 이용해 answer구하기
while (L <= R) {
long mid = (int) ((L + R) / 2);
if (determination((int)mid)) {
ans = mid; //가능하면 저장
L = mid + 1; //하고 왼쪽 떙겨오기
}else{
R = mid - 1;
}
}
System.out.println(ans);
}
public static void main(String[] args) {
input();
pro();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class BOJ_2110 {
/**
* 최 대 거 리
* 어떤 거리만큼 거리를 둘 때 공유기 c개를 설치할 수 있는가
*
*/
static int C,N;
static int[] A;
static MyScanner sc = new MyScanner();
StringBuilder sb = new StringBuilder();
static void input() {
N = sc.nextInt();
C = sc.nextInt();
A = new int[N + 1];
for (int i = 1; i <= N; i++) {
A[i] = sc.nextInt();
}
}
static boolean determination(int D) {
// TODO : D만큼의 거리를 둔다면 C개 만큼 공유기를 설치할 수 있나
// 가장 많이 설치해보자
// 제일 왼쪽부터 설치, D만큼 거리를 두며 최대로 설치가 개수와 C를 비교
int cnt = 1, last = A[1]; //설치 갯수, 마지막으로 설치한 index
for (int i = 2; i <= N; i++) {
//A[i] 번쨰 설치 가능?
if (A[i] - last >= D) {
cnt++;
last = A[i];
}
}
return cnt >= C;
}
static void pro() {
// 빠른 determination을 위한 정렬
int L = 1, R = 10000000, ans = 0;
Arrays.sort(A,1,N+1);
// [L ... R] 범위 안에 정답 존재
// 이분 탐색과 determination 문제를 이용해 ans 구하기
while (L <= R) {
int mid = (L + R) / 2;
if (determination(mid)) {
ans = mid;
L = mid + 1;
}else{
R = mid - 1;
}
}
System.out.println(ans);
}
public static void main(String[] args) {
}
}
class MyScanner{
BufferedReader br;
StringTokenizer st;
public MyScanner(){
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
Long nextLong() {
return Long.parseLong(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
MyScanner
class MyScanner{
BufferReader br;
StringTokeniger st;
public MyScanner(){
br = new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while(st == null || !st.hasMoreElements()){
try{
st = new StringTokeniger(br.readLine());
}catch(IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt(){
return Integer.parseInt(next());
}
long nextLong(){
return Long.parseLong(next());
}
double nextDouble(){
return Double.parseDouble(next());
}
String nextLine(){
String str = "";
try{
str = br.readLine();
} catch(IOException e){
e.printStackTrace();
}
return str;
}