CSU 1803:2016 Problem Solving Report

I didn't have the habit of writing blogs, but today I looked back at the questions I had written, and found that I couldn't understand the code at all, and I had no idea at all when I looked at the questions.

Closer to home, topic link: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1803

When I saw the title, my first impression was the decomposition factor, that is, 2016=1*2016=2*1008=………… If you decompose the prime factor of 2016, you will know how many kinds there are. 2016 = 2^5 * 3^2 * 7. Well, this manual calculation is a bit troublesome. And there is another point, the title requires a*b to be a multiple of 2016. If c*d=2016, then (xc, yd) all meet the conditions. In this way, we only need to find the number of x and y corresponding to (c, d). Obviously x <= m/c, y <= n/d. This is simple, just open two arrays and store the x and y corresponding to c and d. For c and d, a layer of for loop can be traversed once. After finding the corresponding x, y, there is another troublesome problem-judgment weight, obviously, the multiple of 2016 is also a multiple of 1008, so according to the principle of tolerance and exclusion, we can subtract a multiple of 2016 from the number of multiples of 1008 number. Then when we continue to count, when we reach 504, we find that we need to calculate a multiple of 504, but not a multiple of 1008, nor a multiple of 2016 (yes, 2016 is a multiple of 1008, but we have already subtracted it, So the number of multiples of 1008 we store should actually be multiples of 1008, not multiples of 2016), this process can be processed with a layer of for loops, and then finally traversed with two layers of for loops Get i and j of i*j==2016, then multiply the number of multiples of i by the number of multiples of j, and finally add it to the counter.

The final code is as follows:



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>

using namespace std;
typedef long long LL;
intmain()
{
//    freopen("in.txt", "r", stdin);
    LL m, n;
    while(~scanf("%lld%lld", &m, &n))
    {
        LL M[2017] = {0}, N[2017] = {0};
        for(int i = 2016; i; -- i)
        {
            M[i] = m/i;
            N[i] = n/i;
            for(int j = i+1; j < 2017; ++ j)
                if(j % i == 0 && 2016 % i == 0 && (2016/i) % (j/i) == 0)
                    N[i] -= N[j];
        }
        LL ans = 0;
        for(int i = 1; i < 2017; ++ i)
            for(int j = 1; j < 2017; ++ j)
                if(i * j == 2016)
                   years += M[i]*N[j];
        printf("%lld\n", ans);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326026119&siteId=291194637