五个不同自然数a < b < c < d < e 满足a^2 + b^2 + c^2 + d^2 + e^2 = abcde。给出1个数N,求e <= N的全部的解。
输入
输入1个数N(0 <= N <= 10^18)。
输出
第1行:1个数N,N为解的数量。 第2 - N + 1行:每行5个数,中间用空格分隔,对应a,b,c,d,e。解按照a,b,c,d,e依次排序。如果无解,输出No Solution。
输入样例
200
输出样例
2 1 3 4 9 107 1 3 5 12 179
感觉很棘手。尝试能否通过一组解来构造另一组解(最小的一组解不大)。
a2+b2+c2+d2+e2=abcde⇒b2+c2+d2+e2=abcde−a2a2+b2+c2+d2+e2=abcde⇒b2+c2+d2+e2=abcde−a2。
尝试替换一个数,将aa替换为a′a′。
a′2+b2+c2+d2+e2=a′bcdea′2+b2+c2+d2+e2=a′bcde
于是有a′2+abcde−a2=a′bcde⇒a′2+abcde−a2=a′bcde⇒
a′2−a2=bcde(a′−a)⇒(a′+a)(a′−a)=bcde(a′−a)⇒a′2−a2=bcde(a′−a)⇒(a′+a)(a′−a)=bcde(a′−a)⇒
a′+a=bcde⇒a′=bcde−aa′+a=bcde⇒a′=bcde−a
所以,若a,b,c,d,e是一组解,则
bcde-a,b,c,d,e/a,acde-b,c,d,e…也是满足式子①。
然后就可以根据某一组a,b,c,d,e暴力构造出所有答案。
我也不知道为什么跑这么快。
还有个问题。必须满足a<b<c<d<ea<b<c<d<e,所以输出的时候只输出满足a<b<c<d<ea<b<c<d<e的。
不要在暴力过程中将不满足a<b<c<d<ea<b<c<d<e的删去,因为通过这样的a,b,c,d,e,仍然可以构造出满足a<b<c<d<ea<b<c<d<e的a,b,c,d,e。
所有的a,b,c,d,e用个哈希判一下。
#include<cstdio>
#include<algorithm>
#include<map>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<ll,ll> pi;
typedef pair<pi,pi> pii;
typedef pair<pii,ll> piii;
const ll lim=2e18;
const int maxt=700000,maxx=40000;
map<piii,bool> ha;
piii zlt;
struct dong{
ll a,b,c,d,e;
} ans[2500];
ll dl[maxt+1000][5],a[5],b[5];
int i,j,k,l,m,head,tail,top;
ll n,t;
bool czy;
bool cmp(dong a,dong b){
if (a.a<b.a||a.a==b.a&&a.b<b.b) return 1;
if (a.a==b.a&&a.b==b.b&&a.c<b.c||a.a==b.a&&a.b==b.b&&a.c==b.c&&a.d<b.d) return 1;
if (a.a==b.a&&a.b==b.b&&a.c==b.c&&a.d==b.d&&a.e<b.e) return 1;
return 0;
}
piii mk(ll a,ll b,ll c,ll d,ll e){
pi l=make_pair(a,b),r=make_pair(c,d);
pii m=make_pair(l,r);
return make_pair(m,e);
}
int main(){
//freopen("data.out","w",stdout);
czy=1;
/*fo(i,1,200)
fo(j,i,200)
fo(k,j,200)
fo(l,k,200)
fo(t,l,200)
if (i*i+j*j+k*k+l*l+t*t==i*j*k*l*t){
printf("%d %d %d %d %d\n",i,j,k,l,t);
}*/
head=0;tail=1;
dl[1][0]=1;dl[1][1]=1;dl[1][2]=3;dl[1][3]=3;dl[1][4]=4;
zlt=mk(1,1,3,3,4);
ha[zlt]=1;
/*dl[2][0]=1;dl[2][1]=3;dl[2][2]=5;dl[2][3]=12;dl[2][4]=179;
zlt=mk(1,3,5,12,179);
ha[zlt]=1;
dl[3][0]=1;dl[3][1]=3;dl[3][2]=4;dl[3][3]=35;dl[3][4]=417;
zlt=mk(1,3,4,35,417);
ha[zlt]=1;
dl[4][0]=1;dl[4][1]=3;dl[4][2]=5;dl[4][3]=44;dl[4][4]=657;
zlt=mk(1,3,5,44,657);
ha[zlt]=1;
dl[5][0]=1;dl[5][1]=3;dl[5][2]=9;dl[5][3]=23;dl[5][4]=620;
zlt=mk(1,3,9,23,620);
ha[zlt]=1;
dl[6][0]=1;dl[6][1]=3;dl[6][2]=12;dl[6][3]=31;dl[6][4]=1115;
zlt=mk(1,3,12,31,1115);
ha[zlt]=1;
dl[7][0]=1;dl[7][1]=4;dl[7][2]=9;dl[7][3]=33;dl[7][4]=1187;
zlt=mk(1,4,9,33,1187);
ha[zlt]=1;*/
while (head<tail){
if (tail>=maxt){
t=t;
break;
}
if (head==1331){
t=t;
}
++head;
fo(i,0,4) a[i]=dl[head][i];
fo(i,0,4){
fo(j,0,4) b[j]=a[j];
t=1;
czy=1;
fo(j,0,4)
if (j!=i){
if (t>lim/a[j]){
czy=0;
break;
}
t*=a[j];
}
if (!czy) continue;
t-=a[i];
b[i]=t;
sort(b,b+5);
if (b[0]<=0) continue;
/*if (tail>=maxx) {
czy=1;
fo(j,1,4)
if (b[j]==b[j-1]){
czy=0;
break;
}
if (!czy) continue;
}*/
zlt=mk(b[0],b[1],b[2],b[3],b[4]);
if (b[0]==9&b[1]==23&&b[2]==620&&b[3]==128337&&b[4]==1830085619){
t=t;
}
if (!ha[zlt]){
ha[zlt]=1;
++tail;
fo(j,0,4) dl[tail][j]=b[j];
}
}
}
fo(i,1,tail)
if (dl[i][0]==1&&dl[i][1]==3&&dl[i][2]==5&&dl[i][3]==12&&dl[i][4]==179) break;
//printf("%d\n",i);
scanf("%lld",&n);
fo(i,1,tail){
if (dl[i][4]>n) continue;
if (dl[i][0]==dl[i][1]||dl[i][1]==dl[i][2]||dl[i][2]==dl[i][3]||dl[i][3]==dl[i][4]) continue;
++top;
ans[top].a=dl[i][0];ans[top].b=dl[i][1];
ans[top].c=dl[i][2];ans[top].d=dl[i][3];
ans[top].e=dl[i][4];
}
if (!top) printf("No Solution\n");
else{
sort(ans+1,ans+top+1,cmp);
printf("%d\n",top);
fo(i,1,top) printf("%lld %lld %lld %lld %lld\n",ans[i].a,ans[i].b,ans[i].c,ans[i].d,ans[i].e);
}
}