这道题我一开始的思路是枚举这个i和当前是第k年(倒着枚举k),用b数组记录每个荷叶上青蛙分到的食物,如果当前的这个
b
k
b_k
bk是和i相等的那么就说明我们找到了满足条件且是最早的一年,如果一直枚举完都没有找到满足题意得则输出-1.时间复杂度为 O(n*
a
i
a_i
ai),超时。
我们把所有的floor(a[k]/i)的所有取值区域都拿出来,把所有区域划分为
1
1
1~
1
0
8
10^8
108 ,这样会划分出来
n
∗
1
0
4
n*10^4
n∗104段
因为对于每一段内部每一个
f
l
o
o
r
(
a
[
k
]
/
i
)
floor(a[k]/i)
floor(a[k]/i)都不会改变的。
因此我们可以直接扫一遍模拟
a
[
k
]
/
i
a[k]/i
a[k]/i变化的过程,这里的u数组和frog数组都需要开大一点,应为u数组代表着每个荷叶上青蛙分到的食物相同的青蛙的数量。
#include<bits/stdc++.h>
using namespace std;
vector<int> v;
int main()
{
int n,k;
cin>>n;
int a[1005],u[1005],frog[1005];
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
{
int k=1;
while(1)
{
v.push_back(k);
if(!(a[i]/k))
break;
k=a[i]/(a[i]/k)+1;
}
}
sort(v.begin(),v.end());
v.resize(unique(v.begin(),v.end())-v.begin());
for(int i=0;i<v.size();i++)
{
for(int j=0;j<n;j++)
u[j]=a[j]/v[i];
sort(u,u+n);
for(int j=0;j<n;)
{
k=j;
while(k<n&&u[j]==u[k])
k++;
if(!frog[k-j])
frog[k-j]=v[i];
j=k;
}
}
for(int i=1;i<=n;i++)
cout<<frog[i]-(!frog[i])<<endl;
return 0;
}