수학 공부 열심히 한다는 마음으로 항상 틀리며 공부하고있다 ㅎㅎ 이 문제를 풀 때 혼자 너무 어렵게 접근해서 처음에는 반도 못갔다 코포 끝나고 혼자 풀어보니까 f(a,b) = a&(-b) 로 정리된다는걸 깨달았다 근데 거기서 발전은 못해서 에디토리얼을 봤다 ㅎㅎ 어렵다..!! 결국 a1~an까지 정리하면 a1&(-a2)&(-a3)&(-a4)...&(-an)이 된다는 걸 알 수 있다 그럼 여기서 주목할 건 내가 어떤 2^k 승의 비트를 가지는 수가 1개라면 그걸 a1에 놨을 때 나머지 a2~an까지 -가 붙기 때문에 2^k 위치를 살려준다! 예를들어 2^5 비트가 1인 수가 딱 1개만 있고 그걸 a1에 둔다면 나머지 수들은 2^5가 0이지만 -가 붙어서 1로변하고 a1에 놓인 2^5가 계속 1일 수 있다 ..
이런 수학문제가 참 어려운거같다 나는 한참 생각하고 틀린 문제다 혼자 식을 줄이려고 애썼는데 안떠오른다.. 이 문제는 m이 1000이하인게 힌트다! 먼저 2가지 경우가 있을 수 있다 1. nm인 경우 이 경우를 생각도 못했다. 만약 n>m이라면 어떻게 될까? %m해서 나올 수 있는 값은 총 m개다 근데 m보다 큰 n에 대해 %m을 한다면 비둘기집의 원리에 의해 누군가 하나는 같은게 나올 수 밖에 없다!! 생각도못함..! 같은게있다는말은 빼면 0이된다는 말이고 결국 곱하기 0이 생긴다는거니까 0이다 그냥! 그냥 0..! 수학공부를 다시 해야할까보다.. 소스코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include using namespace ..
풀려고 생각하다가 끝난 문제였다 한시간이 넘도록 생각해도 못풀었다 ㅎㅎ 수학적 머리가 없는건가 우선 f,g 계수들의 gcd가 1이기 때문에 어딘가 p로 안나눠떨어지는 수가 하나씩은 나온다! f에서 그위치를 i / g에서는 j라고 해보자 f*g=h일때 h의 계수를 생각해보면 h^(i+j)의 계수는 f와g의 index합이 i+j인것들의 합이다 이 때 fi*gj도 포함되는데 이 수는 각각 p로 안나눠지므로 두 수의곱도 당연히 안나눠진다! 그래서 답은 그냥 안나눠지는 위치 두개를 찾아서 더하면 된다 수학적으로 증명해서 알려주면 참 쉬워보이는데 시간안에 어케해야할까 이걸..!! 수학은 어렵다..! 소스코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include using nam..
bi = (ai*2-1,ai*2)일 때 1~2n 까지 숫자를 두는게 가능한지 보는 문제다 그리디로 내가 앞에서부터 작은수를 채워나가면 된다 이럴때는 upper_bound를 쓰자!! 먼저 set에 1~2n까지 나오지 않은 숫자를 담아준다 그리고 upper_bound를 통해 현재 위치를 만족시켜주는 가장 작은 숫자를 찾자 만약 없다면 -1! 소스코드 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 31 32 33 34 35 36 #include using namespace std; #define ll long long bool check[222]; int main(){ int t; scanf(" %d",&t); ..
코포할때 풀어서 맞은줄알았는데 56번 테케에서 틀렸다~~! long long 썼어야하는데 안써서 틀렸다~~! 문제를 푸는 방법은 그냥 앞에서부터 쭉 봤다 같은 문자열 더미는 하나라고 생각하면 된다 1~n까지 가는데 드는 총 비용을 먼저 구하자 이 부분에서 long long 나올 수 있다..! 그리고 앞에서부터 보면서 한 더미씩 안갔을 때 총합이 p보다 작은지 확인하자! 소스코드 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include using namespace std; #d..
A,B,C중에 오히려 가장 쉬운 문제가 아니였나 싶다(?) 문제 자체 이해는 어려웠다 S라는 문자열 안에서 등차수열로 이루어진 T라는 문자열을 숨겼다 이 때 문자열 T의 수들 중 최댓값을 찾는 문제다 생각하다보면 문제가 쉬워진다 한번 정리를 해보자 1. 길이가 1일 때 => max(alpha[26]) 중 하나다 2. 길이가 2일 때 => for문을 통해 입력받으면서 보면 된다max(d[26][26]) 3. 길이가 3일 때 => 여기부터 생각해봐야한다 꼭 봐야할까? 길이가 3이상이라면 길이가 2인것들을 무조건 포함해야만 만들 수 있다 따라서 볼 필요가 없다! 2까지만 보면 된다! 그럼 바로 쉬운문제로 변한다! 문제에서 필요로 하는것들만 뽑아내는 능력이 이럴때 쓰이는건가..! 이 문제는 쉬워서 다행히 잘 보..
ABC중에 제일 어려웠던 문제같다.. (0,0) -> (0,x)까지 주어지는 숫자의 길이만큼만 이동해서 가야한다 우선 가장 쉬운경우 1. x길이만큼의 수가 주어지는경우 == 1 2. x보다 큰 수가 주어지는 경우 == 2 (삼각형을 만들면 된다) 3. 위에 둘다 아니라면 그 중에 가장 큰걸로 가보면 된다 만약 나머지 수로 x가 나눠떨어진다면 그만큼만 가면 되는거고 조금 더 필요하면 마지막에 삼각형을 만든다는 생각으로 하나 더 쓰면 된다! 이런걸 빠르게 생각하는게 아직은 좀 어려운듯 하다! 소스코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include #include using namespace std; int t; int main..
처음에 문제 이해를 잘못했다 문제는 첫번째칸에 가장 큰 수를 만들라는 문제다 그럼 거리를 보고 만약 다른칸에 수가 0이 아니라면 그만큼 옴기면 된다! 소스코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include #include #include #include using namespace std; int arr[111]; int ans; int main() { int t; scanf(" %d", &t); while (t--) { memset(arr, 0, sizeof(arr)); int n, m; scanf(" %d %d", &n, &m); ans = 0; for (int i = 0; i
문제를 처음 보고 정확하게 어떻게 풀어야 답이 나올지 정리를 못해서 계속 틀렸다 내가 생각한 방법은 무조건 숫자가 들어오면 계속 더해서 보관했다 그렇게하면 합치지 말아야 할 경우에 반례가 생긴다 방법은 작은 숫자부터 그리디하게 보면 해결된다 먼저 내가 받아온 숫자의 합이 n보다 작다면 -1이다 왜냐면 숫자를 계속 나눌수 있어서 1로 나눠서 다 합칠 경우에 어떤수든 성립 가능하다 만약 합이 더 클 때 Bit배열을 만들어서 계속 보관한다 그리고 n의 비트를 0번째부터 보면서 한번 답을 구해보자 만약 Bit[i]가 켜있다면 하나를 빼서 쓰면 된다 여기서 내가 캐치하지 못했던 부분이 있다 아래서부터 보기때문에 이제 더이상 Bit[i]는 필요없다 그래서 Bit[i+1]로 합쳐주면 된다 Bit[i+1] += Bit..