主要就是从最后一个点开始循环
假设这个点为完美数列的最后一个
找到第一个m * p >= M
然后相减得到数列的个数
最后由于p《=10的九次 ,数列中的数字小于10的九次相乘可能大于int的值所以需要用long long。
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
long long n,p,num[100010];
scanf("%lld %lld",&n,&p);
for(int i = 0;i<n;i++)
{
scanf("%lld",&num[i]);
}
sort(num,num+n);
int ans=-1;
for(int i = n - 1;i>=0;i--)
{
int left = 0,right = i,mid = 0;
while(left <= right)
{
mid = (left + right) /2;
if(num[mid] * p == num[i])
break;
else if(num[mid] * p > num[i])
right = mid - 1;
else if(num[mid] * p < num[i])
{
if(left == right)
mid++;
left = mid + 1;
}
}
if(ans < i - mid + 1)
ans = i - mid + 1;
}
printf("%d",ans);
}
two points方法
错了一个节点
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
long long n,p,num[100010];
scanf("%lld %lld",&n,&p);
for(int i = 0;i<n;i++)
{
scanf("%lld",&num[i]);
}
sort(num,num+n);
int ans=-1;
int left = 0,right = n - 1;
while(left <= right)
{
if(num[left] * p < num[right] )
{
if(num[right] - num[right - 1] > num[left + 1] * p - num[left] * p)
right--;
else
left++;
}
if(num[left] * p >= num[right] )
break;
}
if(ans < right - left + 1)
ans = right - left + 1;
printf("%d",ans);
}
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n,p;
long long num[100010];
scanf("%d %d",&n,&p);
for(int i = 0;i<n;i++)
{
scanf("%lld",&num[i]);
}
sort(num,num+n);
int ans=-1;
int l = 0,r = 0,c = 0;
while(l<n && r<n)
{
while(num[l] * p >= num[r] && r<n)
{
c = max(c,r - l + 1);
r++;
}
l++;
}
printf("%d",c);
}
学习算法笔记的two points