所有题链接: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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Maxx = 4e6 + 7;
int n, m;
int a[2005], b[2005];
map <int, int> 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 <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
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);
}