广东省赛补题_D
lianjie
注意设置标志的妙用,在重复判断边界中,设置一个越界岗哨可以避免重复的判断。把越界位置根据题意设置成inf,就不用一次次的判断
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
const int N=5e5+100;
const int inf=1e9;
ll a[N];
ll Max_val=-1;
int ans[N]; //答案数组,存下标
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
Max_val=max(Max_val,a[i]);
}
a[0]=1500000000; //越界位置设置标志,岗哨
a[n+1]=1500000000;
int cnt=0;
for(int i=1;i<=n;i++)
{
ll res=a[i];
int l=i-1,r=i+1; //和i相邻的两个数
while(1)
{
if(a[l]<=res)
{
l--;
res*=2;
}
if(a[r]<=res)
{
r++;
res*=2;
}
if(res>=Max_val)
{
ans[++cnt]=i;
break;
}
if(res<a[l] && res<a[r]) break; //不能再更新或者是出界,退出(出界也属于不能再更新的条件)
}
}
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
}
不设置越界岗哨AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
const int N=5e5+100;
const int inf=1e9;
ll a[N];
ll Max_val=-1;
int ans[N]; //答案数组,存下标
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
Max_val=max(Max_val,a[i]);
}
// a[0]=1500000000; //设置标志,岗哨
// a[n+1]=1500000000;
int cnt=0;
for(int i=1;i<=n;i++)
{
ll res=a[i];
int l=i-1,r=i+1; //和i相邻的两个数
while(1)
{
if(l>=1 && a[l]<=res) //每使用时都要判断l是否合法
{
l--;
res<<=1;
}
if(r<=n && a[r]<=res)
{
r++;
res<<=1;
}
if(res>=Max_val)
{
ans[++cnt]=i;
break;
}
if(l>=1 && res>=a[l]) continue;
if(r<=n && res>=a[r]) continue;
break;
}
}
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
cout<<ans[i]<<" ";
cout<<endl;
return 0;
}