package 기본수학1;
import java.util.*;
public class 부녀회장이될테야 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
for(int i=0;i<T;i++) {
int k=sc.nextInt();
int n=sc.nextInt();
int[][] people=new int[k+1][n+1];
for(int j=0;j<=k;j++) {
for(int m=1;m<=n;m++) {
if(j==0) {
people[j][m]=m;
}
for(int h=1;h<=m;h++) {
if(j==1) {
people[j][m]+=people[0][h];
}
else if(j>=2){
if(h==1) {
people[j][h]+=people[j-1][h];
}
else if(h>=2) {
people[j][h]+=people[j][h-1]+people[j-1][h];
}
}
}
}
}
System.out.println(people[k][n]);
}
}
}
하다가 빡쳐서 구글링 ..^^
2차원 배열 쓰면 풀 수 있을 거 같았는데 for문 변수들 헷갈려서 구글링 선배님들의 풀이를 보고 다시 배웠다
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 아파트 생성
int[][] APT = new int[15][15];
for(int i = 0; i < 15; i++) {
APT[i][1] = 1; // i층 1호
APT[0][i] = i; // 0층 i호
}
for(int i = 1; i < 15; i ++) { // 1층부터 14층까지
for(int j = 2; j < 15; j++) { // 2호부터 14호까지
APT[i][j] = APT[i][j - 1] + APT[i - 1][j];
}
}
// 테스트 부분
int T = in.nextInt();
for(int i = 0; i < T; i++) {
int k = in.nextInt();
int n = in.nextInt();
System.out.println(APT[k][n]);
}
}
}
import java.util.*;
public class 분수찾기 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int a =sc.nextInt();
int cnt=0;
int n=0;
while(true) {
n++;
cnt+=n;
if(cnt>=a) {
if(n%2==0) {
System.out.println(a-cnt+n+"/"+(cnt-a+1));
}
else {
System.out.println((cnt-a+1)+"/"+(a-cnt+n));
}
break;
}
}
}
}
홈페이지에 있는 거처럼 분수들을 표에 나열해보면 규칙을 찾아볼 수 있다.
표를 45도 정도 돌려서 보면 행마다 규칙성을 확인해볼 수 있는데, 바로한 행에 있는 분수들의 분자 분모 합이 같은 것이다!
행의 변수 n, 분수 개수 cnt, 입력한 숫자 번호 a라 두고 while문을 설정하여 n의 수를 올릴 때마다 cnt를 더한 후, cnt와 a의 크기를 비교한다. 이때 cnt이 a보다 크거나 같다면 해당 n행에 a가 있는 것이 파악되므로 그 때의 if문을 걸어 분자 분모를 구할 수 있다. 짝수 행일 때는 a-cnt+n/cnt-a+1, 홀수 행일 땐 그 반대이다. 구글링해서 나온 다른 분들의 답도 추가했다!
짝수행이라면 분모가 감소하는 방향이니 cnt-a를 먼저 계산해주고 1을 더해준다. 분자는 증가하는 방향이니 반대로 a-cnt를 계산해준 뒤 n을 더하여 양수값을 만들어준다. 갠적으로 난 이 방법이 더 계산하기 편했던 거 같다!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int X = in.nextInt();
int cross_count = 1, prev_count_sum = 0;
while (true) {
// 직전 대각선 누적합 + 해당 대각선 개수 이용한 범위 판별
if (X <= prev_count_sum + cross_count) {
if (cross_count % 2 == 1) { // 대각선의 개수가 홀수라면
// 분모가 큰 수부터 시작
// 분모는 대각선 개수 - (X 번째 - 직전 대각선까지의 누적합 - 1)
// 분자는 X 번째 - 직전 대각선까지의 누적합
System.out.print((cross_count - (X - prev_count_sum - 1)) + "/" + (X - prev_count_sum));
break;
}
else { // 대각선의 개수가 짝수라면
// 홀수일 때의 출력을 반대로
System.out.print((X - prev_count_sum) + "/" + (cross_count - (X - prev_count_sum - 1)));
break;
}
} else {
prev_count_sum += cross_count;
cross_count++;
}
}
}
}
입력받을 X 값
해당 범위의 대각선 칸 개수 ( cross_count )
해당 대각선 직전 대각선 까지의 칸의 누적 합 ( prev_count_sum )
import java.util.*;
public class 달팽이는올라가고싶다 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc= new Scanner(System.in);
int A=sc.nextInt();
int B=sc.nextInt();
int V=sc.nextInt();
int h=A;
int day=1;
while(h<V) {
h-=B;
day++;
h+=A;
}
System.out.println(day);
}
}
값은 맞다. 그러나 예시 3번과 같은 경우 적용했을 때 넘 오래걸린다..
반복문을 쓸 경우 무조건 시간초과되기에 더 적은 시간 소요될 수 있는 알고리즘을 생각해보았다. 우선 A B V간의 관계성을 파악해보았다.
A | B | V | day |
---|---|---|---|
2 | 1 | 5 | 4 |
5 | 1 | 6 | 2 |
100 | 99 | 1000000000 | 999999901 |
그냥 편하게 전체 길이에서 A-B만큼을 나눠주면 되는데 이와 같은 경우 정점에 도달했을 때도 미끄러짐을 전제하에 계산하는 것과 같다. 그러기에 V-B, 즉 정상 도달 전 마지막으로 미끄러지는 길이에서 A-B을 나눠주면 day값 계산 완료. 근데 정확히 나눠지지 않는 경우는 if문으로 예외를 세워 기존 day값에 +1을 해준다..!
놓친부분: 정확히 나눠지지 않는 부분을 어떻게 해결할까에서 고민되었다. 새로 식을 세울까 했는데 그냥 단순히 day++라는 식을 세우면 끝이었음
import java.util.*;
public class 달팽이는올라가고싶다 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc= new Scanner(System.in);
int A=sc.nextInt();
int B=sc.nextInt();
int V=sc.nextInt();
int day=(V-B)/(A-B);
if((V-B)%(A-B)!=0) {
day++;
}
System.out.println(day);
}
}
그런데도 java11에서는 시간초과 떠서 결국 구글링의 힘으로 Buffer 이용한 코드로 작성했다..
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
int range1=1;
int range2=1;
int cnt=1;
while(true){
if(range1<=num && num<=range2){
System.out.print(cnt);
break;
}
else{
range1=range2+1;
range2+=6*cnt;
cnt++;
}
}
}
}
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 h=sc.nextInt();
int w=sc.nextInt();
int n=sc.nextInt();
int y=0;
int x=0;
if(n%h==0){
y=h;
}
else{
y=n%h;
}
if(n%h>0){
x=n/h+1;
}
else if(n%h==0){
x=n/h;
}
if(x<10){
System.out.println(y+"0"+x);
}
else {
System.out.println(y+""+x);
}
}
}
}
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
long A=sc.nextInt();
long B=sc.nextInt();
long C=sc.nextInt();
long cnt=1;
while(true){
if(A+B*cnt<C*cnt){
System.out.println(cnt);
break;
}
else if(B>C){
cnt=-1;
System.out.println(cnt);
break;
}
else{
cnt++;
}
}
}
}
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int A=sc.nextInt();
int B=sc.nextInt();
int C=sc.nextInt();
long cnt=1;
if(B>=C){
cnt=-1;
System.out.println(cnt);
}
else{
cnt=A/(C-B)+1;
System.out.println(cnt);
}
}
}
import java.util.Scanner;
import java.math.BigInteger;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
BigInteger a = sc.nextBigInteger();
BigInteger b = sc.nextBigInteger();
System.out.println(a+b); //or System.out.println(a.add(b));
}
}
<오류코드>
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
String A=sc.next();
String B=sc.next();
int[] C=new int[A.length()];
for(int i=A.length()+1;i>=0;i--){
C[i]=(int)A.charAt(i)+(int)B.charAt(i);
if(C[i]>=10){
C[i]-=10;
C[i-1]+=1;
}
System.out.print(C[i]);
}
}
}
String str_A = input();
String str_B = input();
int max_length = max(str_A.length(), str_B.length());
int[] A = new int[max_length + 1]; // 마지막 자리수 올림이 있을 수 있으므로 +1
int[] B = new int[max_length + 1]; // 마지막 자리수 올림이 있을 수 있으므로 +1
// A 초기화
for(int i = A.length - 1, int idx = 0; i >= 0; i--, idx++) {
A[idx] = str_A.charAt(i) - '0'; // 맨 뒤 문자부터 역순으로 하나씩 저장
}
// B 초기화
for(int i = B.length - 1, int idx = 0; i >= 0; i--, idx++) {
B[idx] = str_B.charAt(i) - '0'; // 맨 뒤 문자부터 역순으로 하나씩 저장
}
// 덧셈
for(int i = 0; i < max_length; i++) {
int value = A[i] + B[i];
A[i] = value % 10; // 더한 값의 10으로 나눈 나머지가 자리값이 됨
A[i + 1] = A[i + 1] + (value / 10); // 더한 값의 10으로 나눈 몫이 올림값이 됨
}
// A배열 역순 출력
// 가장 높은 자리수가 0일 수도 있기 때문에 0이 아닐 경우에만 출력
if(A[max_length] != 0) {
print(A[max_length]);
}
for(int i = max_length - 1; i >= 0; i--) {
print(A[i]);
}
체크 포인트:
int max_length = max(str_A.length(), str_B.length());
A랑 B 길이 중 예시와 다르게 A가 더 길거나 B가 더 길 땐 어떡하지 했는데
max함수를 이용하여 max_length를 정할 수 있었다.
초기화 부분에서 역순으로 하나씩 저장할 때 charAt(i)값에 '0'을 뺀 것
더한 값의 초과 몫을 더할 때 10을 나눈 것.. 단순히 1만 더했었다.
for문에서 범위 설정 중요!!!!!
이런 알고리즘 익숙할 때까지 더 공부하고 생각하는 능력을 길러야겠다..!
charAt(i)만 했을 땐 문자인데, '0'을 빼주면 정수형이다!**
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int N = sc.nextInt();
int cnt=0;
int five=0;
int three=0;
int ans=0;
if(N%5/3>0&&N>=5){
cnt=N%5+N%5/3;
}
else if((N%3+3)%5==0&&N>=3){
cnt=N/3;
}
else{
cnt=-1;
}
if(N%5==0){
five=N/5;
if(cnt<five&&cnt!=-1){
ans=cnt;
}
else
{ans=five;}
if(N%3==0){
ans=five;
}
}
else if(N%3==0){
three=N/3;
if(cnt<three&&cnt!=-1){
ans=cnt;
}
else
{ans=three;}
if(N%5==0){
ans=five;
}
}
else
{
ans=cnt;
}
System.out.println(ans);
}
}
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int N = sc.nextInt();
int cnt=0;
while(true){
if(N%5==0){
System.out.print(N/5+cnt);
break;
}
else if(N<0){
cnt=-1;
System.out.print(cnt);
break;
}
N=N-3;
cnt++;
}
}
}