欧洲区域赛 A F J 题解

所有题链接:http://codeforces.com/gym/101635/attachments

A:

题意:

有两个长度分别为n, m的数组a[ ]  b[ ],求b[ ]元素 与 a[ ]元素所有差值里出现次数最多的那个值,如果有多个最多,打印最小值。

思路:

首先将所有差值,存进tmp数组里,然后开一个map记录这些差值的出现次数,然后用max维护,找到出现最多的次数,然后对差值进行 sort 排序,找到第一次map值等于出现最多的次数,跳出循环输出即可。不懂map用法的,看这个链接,我在这套题解 B题 里讲过map的操作。https://blog.csdn.net/ericgipsy/article/details/80144913

本人AC代码:

#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int Maxx = 4e6 + 7;
int n, m;
int a[2005], b[2005];
map mp;
int tmp[Maxx];

int main() {
    mp.clear();
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= m; i++) scanf("%d", &b[i]);
    int t = 0;
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= n; j++) {
            if(b[i] > a[j]) {
                t++;
                tmp[t] = b[i] - a[j];
                mp[tmp[t]]++;
            }
        }
    }
    int maxT = 0;
    for(int i = 1; i <= t; i++) maxT = max(mp[tmp[i]], maxT);
    sort(tmp + 1, tmp + t + 1);
    int minT = 0;
    for(int i = 1; i <= t; i++) {
        if(mp[tmp[i]] == maxT) {
            minT = tmp[i];
            break;
        }
    }
    printf("%d\n", minT);

}


F:

题意:

签到题,给出举行的宽宽,然后给出组成矩形的每块拼图的面积,求举行长。

思路:

求所有拼图面积和再除以宽即可。

本人AC代码:

#include
#include
#include
#include
#include
using namespace std;
int n, m;
int x, y;

int main() {
    scanf("%d %d", &m, &n);
    int sum = 0;
    while(n--) {
        scanf("%d %d", &x, &y);
        sum += x * y;
    }
    printf("%d\n", sum / m);

}


J:

题意:


给出两个数组,A数组下标 i 表示矩形长,B数组下标 j 表示矩形宽,分别输出,( i+ j ) % 3 == 0, 1, 2的矩形面积和。

思路:

n^2复杂度按题意暴力肯定会TLE,

for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
        if((i + j) % 3 == 0) s1 += a[i] * b[j];
        else if((i + j) % 3 == 1) s2 += a[i] * b[j];
        else s3 += a[i] * b[j];
    }

}

这么写就一定会t掉,不理解题意的看一眼这个代码就知道题意啦,

那么就想办法优化。

记两个余数数组,ma[5], mb[5]; 其中ma[0], ma[1], ma[2]的角标0,1,2分别表示,a[i] % 3的值;而这三个值ma[0], ma[1], ma[2],则表示模3等于角标的a[i]的值的和。mb[0], mb[1], mb[2]也是同理。

然后执行这个操作:

    s0 = ma[1] * mb[2] + ma[2] * mb[1] + ma[0] * mb[0];
    s1 = ma[1] * mb[0] + ma[0] * mb[1] + ma[2] * mb[2];

    s2 = ma[2] * mb[0] + ma[0] * mb[2] + ma[1] * mb[1];

相加形成s0, s1, s2的三项,ma[ i ] 和 mb[ j ]的角标 (i + j) % 3的值即为 s的角标。

本人AC代码:

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 7;
int n;
int a[maxx], b[maxx];
ll ma[5], mb[5];

int main() {
    memset(ma, 0, sizeof(ma));
    memset(mb, 0, sizeof(mb));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    ll s0 = 0, s1 = 0, s2 = 0;
    for(int i = 1; i <= n; i++) {
        if(i % 3 == 0) {
            ma[0] += a[i]; mb[0] += b[i];
        }
        else if(i % 3 == 1) {
            ma[1] += a[i]; mb[1] += b[i];
        }
        else {
            ma[2] += a[i]; mb[2] += b[i];
        }
    }
    s0 = ma[1] * mb[2] + ma[2] * mb[1] + ma[0] * mb[0];
    s1 = ma[1] * mb[0] + ma[0] * mb[1] + ma[2] * mb[2];
    s2 = ma[2] * mb[0] + ma[0] * mb[2] + ma[1] * mb[1];
    printf("%lld %lld %lld\n", s0, s1, s2);
}

你可能感兴趣的:(水题合集)