F - The Pool for Lucky Ones
此题思路非常简单,就是暴力试一遍就知道了。。。因为大家都没过所以错了1次就放弃了。。。赛后发现实在是超级大水题,
唯一的坑 是 ans 需要是_int64 。。。当时就许多人卡在 test36 test36其实就是__int64的数据(最后结果是int64)
暴力1思路是看别人的
假设 i 池往前/后移一个人 然后不断比较当前情况的ans与原来的ans,思路比较清晰
暴力2 是分类,假设最多人的池只有一个,就如何如何,若大于一个,又如何如何,分支比较多 看起来比较复杂
暴力1:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
__int64 a[100000+5];
__int64 tm[100000+5];
int main()
{
//freopen( "C:\\1.txt","r",stdin );
int n;
cin>>n;
__int64 i;
__int64 maxx=0;
for (i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
tm[a[i]]++;
if (a[i]>maxx) maxx=a[i];
}
__int64 j;
__int64 ans=tm[maxx]*maxx;
for (i=1;i<=n;i++)
{
if (a[i]==0) continue;
if (i!=n) //除了i==n,都可以把人往前移动
{
tm[a[i]]--; //
tm[a[i]-1]++; //这两步是把人数为a[i]的池子人数减一(变成a[i]-1的池子)
tm[a[i+1]+1]++;
tm[a[i+1]]--; //这两步是给a[i+1]的池子人数加1(变成a[i+1]+1的池子)
for (j=maxx+1;j>=1;j--)
{
if (tm[j]>0) //找到当前最大人数的池子x 比较ans与( x的人数 * 数量)
{
if (tm[j]*j<ans)
ans=tm[j]*j;
break;
}
}
tm[a[i]]++; //
tm[a[i]-1]--; // 恢复
tm[a[i+1]+1]--;
tm[a[i+1]]++;
}
if (i!=1) //除了i==1,都可以把人往后移动
{
tm[a[i]]--; //
tm[a[i]-1]++; //这两步是把人数为a[i]的池子人数减一(变成a[i]-1的池子)
tm[a[i-1]+1]++;
tm[a[i-1]]--; //这两步是给a[i-1]的池子人数加1(变成a[i-1]+1的池子)
for (j=maxx+1;j>=1;j--)
{
if (tm[j]>0) //找到当前最大人数的池子x 比较ans与( x的人数 * 数量)
{
if (tm[j]*j<ans)
ans=tm[j]*j;
break;
}
}
tm[a[i]]++; //
tm[a[i]-1]--; //这两步是把人数为a[i]的池子人数减一(变成a[i]-1的池子)
tm[a[i-1]+1]--;
tm[a[i-1]]++;
}
}
printf("%I64d\n",ans);
return 0;
}
暴力2:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
struct node
{
__int64 posi;
__int64 vol;
} tm[100000+5];
__int64 nm[100000+5];
__int64 cmp(node a,node b)
{
return a.vol<b.vol;
}
int main()
{
// freopen( "C:\\1.txt","r",stdin );
int n;
cin>>n;
__int64 i;
for (i=1;i<=n;i++)
{
__int64 tt;
scanf("%I64d",&tt);
nm[i]=tt;
tm[i].posi=i;
tm[i].vol=tt;
}
if (n==1)
{
printf("%d\n",tm[1].vol);
return 0;
}
sort(tm+1,tm+1+n,cmp);
__int64 cun=1;
__int64 max=tm[n].vol;
__int64 ans1=max; //???0????
for (i=n-1;i>=1;i--)
{
if (tm[i].vol==max)
cun++;
}
if (cun==1)
{
if (max==1)
{
printf("1\n");
return 0;
}
node tmp=tm[i];
__int64 ttt1=nm[(tm[n].posi+1)]+1;
__int64 ttt2=nm[(tm[n].posi-1)]+1;
__int64 num=1;
for (i=n-1;i>=1;i--)
{
if (tm[i].vol==max-1)
num++;
}
if (tm[i].posi!=n) if (ttt1==max-1)
{
num++;
}
if (tm[i].posi!=1) if (ttt2==max-1)
{
num++;
}
if(num==1)
max--;
printf("%d\n",max);
return 0;
}
__int64 ans=cun*ans1;
__int64 j;
for (i=1;i<=n-cun;i++)
{
if (tm[i].vol==0) continue;
node tmp=tm[i];
__int64 ttt1=nm[(tm[i].posi+1)]+1;
__int64 ttt2=nm[(tm[i].posi-1)]+1;
if (tm[i].posi!=n) if (ttt1>ans1&&ttt1<ans)
{
ans=ttt1;
}
if (tm[i].posi!=1) if (ttt2>ans1&&ttt2<ans)
{
ans=ttt2;
}
}
for (i=n-cun+1;i<=n;i++)
{
node tmp=tm[i];
__int64 ttt1=nm[(tm[i].posi+1)]+1;
__int64 ttt2=nm[(tm[i].posi-1)]+1;
if (tm[i].posi!=n) if (ttt1>ans1&&ttt1<ans)
{
ans=ttt1;
}
if (tm[i].posi!=1) if (ttt2>ans1&&ttt2<ans)
{
ans=ttt2;
}
if (tm[i].posi!=n) if (ttt1<ans1&& (cun-1)*(ans1)<ans)
{
ans=(cun-1)*ans1;
}
if (tm[i].posi!=1) if (ttt2<ans1&& (cun-1)*(ans1)<ans)
{
ans=(cun-1)*ans1;
}
}
printf("%I64d\n",ans);
return 0;
}