题目链接:
题意:
一个整数n,存在整数x,y,z;
满足n=x+y+z, x∣n, y∣n, z∣n ( | 是整除的意思 );
求:x*y*z的最大值,若存在,输出x*y*z;若不存在,则输出-1;
思路:
一开始在比赛的时候是完全没有思路,一直在用很常规的方法想,肯定不行的啊,复杂度太高了,队友很聪明啊
所以我们可以这么想:
设a=n/x,b=n/y,c=n/z(a,b,c必为整数);
所以1/a+1/b+1/c=(x+y+z)/n,因为x+y+z=n,所以1/a+1/b+1/c=1
所以只要求是否有满足的整数a,b,c即可
可得以下三种情况:
(1)a,b,c均为三,1/3+1/3+1/3=1;
答案为n^3/27;
(2)a=2,b=4,c=4,1/2+1/4+1/4=1;
答案为n^3/32;
(3)a=2,b=3,c=6,1/2+1/3+1/6=1;
答案为n^3/36;
因为第三种情况如果包含,必满足第一种情况,所以可写可不写。
有一点很重要,就是会爆int,因为n<=1e6,求答案n^3会爆啊,需要用long long,补题时为此wa一发= =!!
有博友说,打表找规律,发现只有在n%4==0||n%3==0的情况下才有解,目前并不是很清楚打表,先码住,等我学成归来,有知道的人也可以告诉我哦~
我回来了~~
刚刚去看了看打表的概念:通常的用处都是在竞赛的时候对于某题在短时间内不能想出一个完美的算法,然后又能知道它可能出现的各种情况,所以我们就可以用手算或者暴力搜索把各种情况下的结果算出来,然后保存到数组里,最后对应读入的情况输出。
然后我试着写了写对于这道题的打表,不知道对不对呢= =,如果错了还望博友指出,打表代码如下:
#include<stdio.h>
#define MAX 1000
int main()
{
int i,j,k,flag;
for(i=1;i<=MAX;i++)
{
flag=0;
for(j=1;j<=i/3;j++)
{
for(k=j;k<=i/3;k++)
{
if(i%j==0&&i%k==0&&i%(i-j-k)==0)
{
flag=1;
break;
}
}
if(flag==1)
{
printf("%d\n",i);
break;
}
}
}
}
差不多思路就是这样,AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll ;
int main()
{
ll T;
scanf("%lld",&T);
while(T--)
{
ll n;
scanf("%lld",&n);
if(n/3+n/3+n/3==n)
{
printf("%lld\n",n*n*n/27);
}
else if(n/2+n/4+n/4==n)
{
printf("%lld\n",n*n*n/32);
}
else if(n/2+n/3+n/6==n)
{
printf("%lld\n",n*n*n/36);
}
else
{
printf("-1\n");
}
}
}
本文深入探讨了一道关于整数倍数的最大值问题,通过巧妙转换思路,将问题转化为寻找符合条件的整数a、b、c,使得1/a + 1/b + 1/c = 1,最终给出了解决方案并分析了三种可能的情况。
思维&spm=1001.2101.3001.5002&articleId=81981153&d=1&t=3&u=32074710e5a140309f01c8496f559006)
300

被折叠的 条评论
为什么被折叠?



