[백준] 기본 수학2 문풀

백설기·2022년 3월 3일
0

백준 문풀

목록 보기
5/7

1085번 직사각형에서 탈출

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int x = sc.nextInt();
    int y = sc.nextInt();
    int w = sc.nextInt();
    int h = sc.nextInt();
    int P = 0;
    int ans=0;
    
    if(x>=y){
      P=y; //축으로부터의 거리
    }
    else{
      P=x;
    }

    if(w-x>=h-y){
      ans=h-y;
      if(P<ans){
        ans=P;
      }
    }
    else{
      ans=w-x;
      if(P<ans){
        ans=P;
      }
    }
    System.out.print(ans);
  }
}
  • 쉽게 풀었다!

4153번 직각삼각형

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int x=1, y=1, z=1;
    for(int i=0;i<30000;i++){
      x=sc.nextInt();
      y=sc.nextInt();
      z=sc.nextInt();

      if(x!=0&&y!=0&&z!=0){
      if(z*z==x*x+y*y)
      {   System.out.println("right");
        }
      else if(x*x==y*y+z*z){
        System.out.println("right");
      }
      else if(y*y==x*x+z*z){
        System.out.println("right");
      }
      else{
        System.out.println("wrong");
      }
      
    }
      else {
      break;
    }
      }
    
    }
}
  • 조심해야할 부분: zz==xx+yy 뿐만 아니라 xx==..., y*y==... 이 케이스들도 고려해야한다. 조건 파악하기!
  • while문으로도 풀 수 있는데 for문으로 함 풀어보았다.

3053번 택시 기하학

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    double r=sc.nextInt();
    double U=r*r*Math.PI;
    double R=r*Math.sqrt(2);
    double T=R*R;         
    
    System.out.println(String.format("%.6f",U));
    System.out.println(String.format("%.6f",T));
    }
}
  • 체크 포인트: 택시 기하학과 유클리드에서의 반지름 관계를 파악하면 쉬운 문제! Math class 이용해서 PI값과 제곱근을 sqrt를 통해 표현할 수 있었다. 그리고 String.format을 이용하여 문자열 형태로 리턴 받고 소숫점 아래 원하는 수만큼 자릿수를 나타낼 수 있었다. String.format("%.6f",U)는 소숫점 아래 6번째까지 표현할 수 있음! 소숫점 아래 0이어도 절삭하지 않는다. 비슷하게 Math 클래스엔 Math.ceil, Math.floor, Math.round가 있다! (각각 올림, 반올림, 버림이다)

1978번 소수 찾기

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int num=sc.nextInt();
    int cnt=0;
    int count=0;
    for(int i=0;i<num;i++){
      count=0;
      int x=sc.nextInt();
      for(int j=1;j<=x;j++){
       if(x%j==0){
         count++;
         }
        }
         if(count==2)
          cnt++;
    }
    System.out.print(cnt);
    }
}
  • 간단하게 i=1에서부터 입력받은 x값까지 나누어 나눠 떨어지는 부분은 count를 세게 하고, count 개수가 2개인 것을 소수로 여겨 cnt++ 처리해주었다. 근데 첫번째 for문 안에 count=0을 안넣어주니 count가 계속 0값이 나왔다. 지역변수 처리를 해줘야하나봄..!

  • 소수 구하는 법은 더 있는데 이 문제에선 2부터 X-1까지 나누라했으므로 풀이는 일단 이렇게!

2581번 소수

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int M=sc.nextInt();
    int N=sc.nextInt();
    int sum=0;
    int min=N;
    int cnt=0;
    int ans=0;
    int count=0;
    for(int i=N;i>=M;i--){
      cnt=0;
      for(int j=1;j<=i;j++){
        if(i%j==0){
          cnt++;
            }
            }
       if(cnt==2){
         count++;
            sum+=i;
             if(min>i){
              min=i;
          }
      }
      else if(cnt!=2){
        ans=-1;
      }
    }
    if(count==0){
      System.out.println(ans);
    }
    else{
    System.out.println(sum);
    System.out.println(min);
      }
    }
}
  • 초기 설정 변수가 많다 .. 나중에 시간되면 코드 더 간단하게 해서 풀어볼 수는 없을까?
  • 체크 포인트: 우선 i%j==0으로 나머지 0일 때 수를 cnt로 세고, 그 수가 자기 자신과 1이면 소수이니 cnt==2일때 소수들의 합을 sum으로 구했다. 이때 count++처리를 하여 소수가 나온 경우의 수를 구했다. 그리고 그 때 min>i이면 i값을 최소값으로 정했다. 최소값을 구해야하니 for문에서 i 초기값을 N으로 하고 M보다 크다고 조건을 걸어 i--로 for문을 돌렸다. 그리고 cnt값이 2가 아닐 경우 새로운 ans값을 만들어 -1로 정했다. for문에서 벗어나 if문을 통하여 count의 개수, 0인지 아닌지에 따라 나오는 출력문을 ans로 할지 sum, min으로 할지 정해주었다!

11653번 소수

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int N=sc.nextInt();
    int i=2;
    int num=1;
    while(N!=num){ 
      if(N==1){
        break;
      }
      if(N%i==0){
        N=N/i;
        num*=i;
        System.out.println(i);
      }
      else{
        i++;
      }
    }
    }
    }
  • 콘솔상으로는 맞지만 백준 제출시 시간 초과 뜸..
import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int N=sc.nextInt();
  
    for(int i=2;i<=Math.sqrt(N);i++){
      while(N%i==0){
        System.out.println(i);
        N/=i;
      }
    }    
    if(N!=1)
        System.out.println(N);
    }
    }
  • Stranger's Lab님의 코드를 참고하였다. (감사합니다) for문으로 i를 돌려가며, while문의 조건을 N%i==0으로 설정하여 안나눠질때까지 while문을 도는 것..! 조건 설정을 잘했더라면 오류가 나지 않았을텐디..

3009번 네번째점

오류났던 코드

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int X=0;
    int Y=0;
    int ansx=0;
    int ansy=0;
    int[] x= new int[3];
    int[] y= new int[3];
    for(int i=0;i<3;i++){
      x[i]=sc.nextInt();
      y[i]=sc.nextInt();
      for(int j=0;j<3;j++){
        if(x[i]!=x[j]){
          if(x[i]>x[j])
          {X=x[i]-x[j];
          ansx=x[j]+X;
            }
          else if (x[i]<x[j]){
            X=x[j]-x[i];
            ansx=x[i]+X;
          }
        else
            ansx=x[i];
        if(y[i]!=y[j]){
          if(y[i]>y[j])
          {Y=y[i]-y[j];
          ansy=y[j]+Y;
            }
          else if (y[i]<y[j]){
            Y=y[j]-y[i];
            ansy=y[i]+Y;
          }
          }
        else
          ansy=y[i];
      }
      }
    }
    System.out.print(ansx+" "+ansy);
    }
}
  • 배열로 비교만 하니 마지막 예시 입력과 같은 경우 y에서 다른 값을 출력해낸다. 원래 주어진 x, y 좌표들 중 젤 겹치지 않는 걸 답이라 여겨 그대로 출력해야하는데 3차원 배열을 생각치 못했다.!
import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int X=0;
    int Y=0;
    int[] one= {sc.nextInt(), sc.nextInt()};
    int[] two= {sc.nextInt(), sc.nextInt()};
    int[] three= {sc.nextInt(), sc.nextInt()};
    
    if(one[0]==two[0])
      X=three[0];
    else if(one[0]==three[0])
      X=two[0];
    else
      X=one[0];

    if(one[1]==two[1])
      Y=three[1];
    else if(one[1]==three[1])
      Y=two[1];
    else
      Y=one[1];
    
    System.out.print(X+" "+Y);
    }
}
  • 체크 포인트: 좌표계를 표현하기 위해 배열 직접 쓰기 (-> ex. int[] arr={1,2})를 다시금 복기할 수 있었음! 항상 int[] arr=new int[4] 이런 식으로 썼었는데..!

9020번 골드바흐의 추측

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int T=sc.nextInt();
    
    for(int i=0;i<T;i++){
      int n=sc.nextInt();
      boolean[] prime=new boolean[n+1];
      int min=n;
      int p=n/2;  
      prime[0]=prime[1]=false;
      for(int k=2;k<=n;k++){
        prime[k]=true;
      }
      
      for(int k=2;k*k<=n;k++){
        for(int j=k*k;j<=n;j+=k){
          prime[j]=false;
        }
      }

      for(int k=n/2;k<=n;k++){
        if(prime[p]==true&&prime[k]==true){
          System.out.println(p+" "+k);
          break;
          }
        else
          p--;
      }
      
     
      }
    }
    }
  • 소수인지 아닌지, 그리고 문제에서 주어진대로 소수들의 합으로만 구할 수 있는 거까진 구했는데 소수들간 뺄셈값이 적은 것을 어떻게 추릴지 정하지 못함. 그래서 주어진 n의 반절값들로 if문을 돌려 if문 안에 값이 해당된다면 그대로 출력, 아니면 p값은 p--, k값은 k++ (for문에서) 처리해주어 중간에서부터 값을 찾아나간다!

1929번 소수 구하기 (에라토스테네스의 해)

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int M = sc.nextInt();
    int N = sc.nextInt();
    boolean[] prime= new boolean[N+1];
    prime[0]=prime[1]=false;
    //소수면 true
    for(int i=2;i<=N;i++){
      prime[i]=true;
    }
    //2부터 수를 키워가며 배수들을 제외
    for(int i=2;i*i<=N;i++){
      for(int j=i*i;j<=N;j+=i){
        prime[j]=false;
      }
    }
    for(int i=M;i<=N;i++)
      if(prime[i]==true){
    System.out.println(i);
        }
  }
    }
  • 에라토스테네스의 해로 소수 구하기! 2를 제외한 2의 배수들, 3을 제외한 3의 배수들, 5를 제외한 5의 배수들 ... 점점 숫자를 늘려가며 그 이상의 배수들을 제외하면 남아있는 값이 소수라는 걸 알 수 있다. 출력 시간이 매우 빠름!!

4948번 베르트랑 공존

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    while(true){
      int n=sc.nextInt();
      int cnt=0;
      boolean[] prime=new boolean[2*n+1];
      if(n==0)
        break;
      for(int i=1;i<=2*n;i++){
        prime[i]=true;
      }
    
      prime[0]=prime[1]=false;
      for(int i=2;i*i<=2*n;i++){
        for(int j=i*i;j<=2*n;j+=i){
          prime[j]=false;
        }
      }
        
      for(int i=n+1;i<=2*n;i++){
        if(prime[i]==true){
          cnt++;
          }
      }
      System.out.println(cnt);
    }
    }
    }

1002번 터렛

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
 
		Scanner in = new Scanner(System.in);
 
 
		int T = in.nextInt();
 
		while (T-- > 0) {
 
			int x1 = in.nextInt();
			int y1 = in.nextInt();
			int r1 = in.nextInt();
 
			int x2 = in.nextInt();
			int y2 = in.nextInt();
			int r2 = in.nextInt();
			
			System.out.println(tangent_point(x1, y1, r1, x2, y2, r2));
		}
 
	}
 
 
	// 접점 개수 구하는 함수
	public static int tangent_point(int x1, int y1, int r1, int x2, int y2, int r2) {
    
		int distance_pow = (int)(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));	// 중점간 거리 distance의 제곱 
 
 
		// case 1 : 중점이 같으면서 반지름도 같을 경우
		if(x1 == x2 && y1 == y2 && r1 == r2) {
			return -1;
		}
		
		// case 2-1 : 두 원의 반지름 합보다 중점간 거리가 더 길 때 
		else if(distance_pow > Math.pow(r1 + r2, 2)) {
			return 0;
		}
 
		// case 2-2 : 원 안에 원이 있으나 내접하지 않을 때 
		else if(distance_pow < Math.pow(r2 - r1, 2)) {
			return 0;
		}
		
		// case 3-1 : 내접할 때 
		else if(distance_pow == Math.pow(r2 - r1, 2)) {
			return 1;
		}
        
		
		// case 3-2 : 외접할 때 
		else if(distance_pow == Math.pow(r1 + r2, 2)) {
			return 1;
		}
		
		else {
			return 2;
		}
		
	}
 
}
  • 내접, 외접, 만나지 않을 때, 같을 때 if문으로 분류 잘했음! 그러나 Math.pow, Math.sqrt 문을 적재적소 잘 쓰지 못하면서 오류가 잘 남.. 결국 stranger's lab님의 코드를 참고했다. 어느 부분이 틀린걸까..

아래는 내가 쓴 코드

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner sc= new Scanner(System.in);
    int T=sc.nextInt();
    int ans=0;
    for(int i=0;i<T;i++){   
      int x1=sc.nextInt();
      int y1=sc.nextInt();
      int r1=sc.nextInt();
      int x2=sc.nextInt();
      int y2=sc.nextInt();
      int r2=sc.nextInt();
      
      int ptp=(int)Math.sqrt(Math.pow(x2-x1, 2)+Math.pow(y2-y1, 2));
      
      
      if(ptp==r1+r2){
        ans=1;
      }
      else if(ptp==Math.abs(r2-r1)){
          ans=1;
      }
      
      else if(x1==x2&&y1==y2&&r1==r2){
        ans=-1;
      }
      else if(ptp<Math.abs(r2-r1)){
        ans=0;
      } 
      else if(Math.sqrt(ptp)>Math.abs(r1+r2))
      {ans=0;}
        else if(x1==x2&&y1==y2&&r1!=r2){
          ans=0;
        }
      else
          ans=2;
    System.out.println(ans);
      }
    }
    }
profile
뭐든지 할 수 있따 🐶

0개의 댓글