蓝桥杯国赛A组 阅兵方阵
问题描述:
标题:阅兵方阵
x国要参加同盟阅兵活动。
主办方要求每个加盟国派出的士兵恰好能组成 2 个方阵。
x国发现弱小的 y国派出了130人的队伍,他们的士兵在行进中可以变换2种队形:
130 = 81 + 49 = 9^2 + 7^2
130 = 121 + 9 = 11^2 + 3^2
x国君很受刺激,觉得x国面积是y国的6倍,理应变出更多队形。
于是他发号施令:
我们要派出一支队伍,在行进中要变出 12 种队形!!!
手下人可惨了,要忙着计算至少多少人才能组成 12 种不同的双方阵。
请你利用计算机的优势来计算一下,至少需要多少士兵。
(ps: 不要失去信心,1105人就能组成4种队形了)
注意,需要提交的是一个整数,表示至少需要士兵数目,不要填写任何多余的内容。
这个题目乍一看用暴力,哈哈哈三层暴力,问题不大,可试着试着,不对劲,复杂太高,非常耗时。必须用空间换时间。
思路:将两个数平方之和存在类似于哈希表中,只不过该哈希函数就是本身。用暴力算出两个数平方之和放进hash中,然后判断当前hash值是否大于等于12,由题可知,该hash表中,大于12的最小的hash-key为答案。
c/c++实现
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int num[99999999],tmp,ret = 999999999;
int main() {
memset(num,0 ,sizeof num);
for(int i = 1;i <= (1 << 10);i++)
for(int j = i;j <= (1 << 10);j++){
tmp = i*i + j*j;
num[tmp]++;
if(num[tmp] > 11){
ret = min(ret,tmp);
}
}
cout << ret << endl;
for(int i = 1;i <= (1 << 10);i++)
for(int j = i;j <= (1 << 10);j++){
if(i*i + j*j == ret){
cout << i << "*" << i << "+" << j << "*" << j << "=" << ret << endl;
}
}
return 0;
}