題目大意:
ConneR老師想喫東西,他現在在大樓的第s層,大樓總共有n層,但是其中有k層的餐廳關門了。
然後給了這k層關門的餐廳分別所在的樓層。
所以問ConneR老師最少得往上(或者往下)走幾層樓,才能到最近的還開門的餐廳就餐?
解題思路1:
對於關閉的k層,存在數組a裏排序。(放在1~k的位置)
先循環一遍數組a,看看s層是否存在於a數組裏,如果不存在,直接輸出0作爲答案。
如果存在,開始找答案樓層。
數組a第0的位置賦值0,第k+1的位置賦值n+1。(後面的思路計算中有需要)
然後i從0開始循環到k,每次判斷a[i+1]-a[i]是否大於1。
如果大於1,說明a[i+1]與a[i]之間存在着開放的樓層可以成爲目的地。
可以取a[i]+1和a[i+1]-1兩個樓層進行判斷。(因爲s層此時是存在於數組a內的,所以最佳答案樓層一定是相鄰於某個元素的,不想寫那麼多判斷條件的話直接無腦判斷這兩個樓層好了,小貪心一下)
最後輸出最優解即可。
#include<bits/stdc++.h>
using namespace std;
int a[1050];
void solve(){
int n,s,k,d,i,p,ans;
cin>>n>>s>>k;
for(i=1;i<=k;i++)
cin>>a[i];
sort(a+1,a+1+k);
a[0]=0;
a[k+1]=n+1;
ans=10000;
bool flag=true;
for(i=0;i<=k;i++){
if(a[i]==s||a[i+1]==s)
flag=false;
if(a[i+1]-a[i]>1){
ans=min(ans,abs(s-a[i+1]+1));
ans=min(ans,abs(s-a[i]-1));
}
}
if(flag)
ans=0;
cout<<ans<<endl;
}
int main(){
int T;
cin>>T;
while(T--)
solve();
return 0;
}
解題思路2:
同樣的,排序後先循環一遍數組a,看看s層是否存在於a數組裏,如果不存在,直接輸出0作爲答案。
如果存在,因爲只有連續的幾層樓相鄰關閉的時候纔會使答案增大。
所以從s層開始,向上向下都搜一遍最少走幾層能到a[i+1]-a[i]大於1的樓層。(即這兩層樓之間一定有樓層是開放的)
#include<bits/stdc++.h>
using namespace std;
int a[1050];
void solve(){
int n,s,k,i,p,sp,ans;
cin>>n>>s>>k;
bool flag=true;
for(i=1;i<=k;i++){
cin>>a[i];
if(a[i]==s)
flag=false;
}
if(flag){
cout<<0<<endl;
return;
}
sort(a+1,a+k+1);
sp=find(a+1,a+1+k,s)-a;
a[0]=0;
a[k+1]=n+1;
ans=10000;
for(i=sp;i<=k;i++)
if(a[i+1]-a[i]>1){
ans=min(ans,a[i]+1-s);
break;
}
for(i=sp;i;i--)
if(a[i]-a[i-1]>1){
ans=min(ans,s-(a[i]-1));
break;
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}