1. 程式人生 > >2018/11/30 週五集訓隊第七次測試賽補題題解

2018/11/30 週五集訓隊第七次測試賽補題題解

A - Coins CodeForces - 1061A

上來先把題目看錯。。。我以為要求所有滿足的個數,沒想到求滿足的數字的最小的個數。這樣直接套一個整除即可

程式碼(演算法四行)

#include <bits/stdc++.h>
using namespace std;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,s;
  cin>>n>>s;
  if(s%n==0)
  cout<<s/n;
  else
  cout<<s/n+1;
}

B - Views Matter CodeForces - 1061B

自己把自己搞暈的一道題,實際上排個序會變得簡單明瞭。具體的步驟凱哥已經說清楚了,這裡我提供一下我自己的簡單的實現凱哥思路的方法

①首先輸入排序這個沒有什麼區別

②記錄一下最高能到多高,這個意思是說如果升序排序的時候右邊比左面高,那麼高度加一如果高度相同,那麼高度不變

③最後的剩餘的個數就是用列數n+right(最大高度)-目前的高度,然後輸出原來的總數-剩餘的即可。這樣程式碼量也不是很大

④注意用long long!!!

程式碼

#include <bits/stdc++.h>
using namespace std;
long long num[100005];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long n,m,sum=0,t=0,re=0;
  cin>>n>>m;
  for(int i=0;i<n;i++)
  cin>>num[i],re+=num[i];
  sort(num,num+n);
  for(int i=0;i<n;i++)
  if(num[i]>t)
  t++;
  sum=n+(num[n-1]-t);
  cout<<re-sum;
}

C - Vasya and Book CodeForces - 1082A

這個玩意我上來就bfs,一看這個不是bfs模板題嗎。然後無助的卡在第七個點tle。實際上這個東西因為邊界的問題是可以找規律的。具體的解法林姐也說的挺清楚的了,我這裡提供一下我的實現方法

總共有三種情況

①直接能夠到達

②通過1中轉

③通過n中轉

其中②和③還得注意中轉之前的那些步數也得算上。然後判斷一下如果條件都不符合那麼肯定是不行的。如果條件符合求個最小值即可

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t;
  cin>>t;
  while(t--)
  {
    int n,x,y,d,ans1=0,ans2=0,ans3=0,ans=INT_MAX,f=0,ff=0,fff=0;
    cin>>n>>x>>y>>d;
    if(abs(x-y)%d==0)//第一種情況
    {
      f=1;
      ans1=abs(x-y)/d;
      ans=min(ans,ans1);
    }
    if((y-1)%d==0)//第二種情況
    {
      ff=1;
      if((x-1)%d==0)
      ans2+=(x-1)/d;
      else
      ans2+=(x-1)/d+1;
      ans2+=(y-1)/d;
      ans=min(ans,ans2);
    }
    if((n-y)%d==0)//第三種情況
    {
      fff=1;
      if((n-x)%d==0)
      ans3+=(n-x)/d;
      else
      ans3+=(n-x)/d+1;
      ans3+=(n-y)/d;
      ans=min(ans,ans3);
    }
    if(!f&&!ff&!fff)
    cout<<-1<<"\n";
    else
    cout<<ans<<"\n";
  }
}

D - Vova and Trophies CodeForces - 1082B

又是這種我不擅長的模擬題。。。

思路也是看了凱哥(完全復讀)

①預處理一下,把兩邊都加上一個S

②掃一遍找到串中S的下標所在

③判斷情況

(1)如果裡面只有預處理的兩個那麼肯定原串沒有S,所以直接輸出原串長度即可

(2)如果裡面比預處理多了一個S,那麼肯定原串裡面肯定是隻有一個S的。顯然這樣直接輸出原串-1

(3)如果原串裡面有多個S那麼需要對每三個S進行一次判斷。因為這個題的規律就是供給或者內銷。供給就是這三個S卡的G是否可以從外面換進一個G或者內銷就是把原來不相連的G相連

(3).1這個地方還有一個判斷的問題。如果我們直接判斷位置的話那是不行的。因為可能串的後面都是S也說不定呢。。。

(3).2這個地方凱哥用的方法是直接判斷剩餘的S與剩餘的串的字元的個數進行比較。如果剩餘的S少,那麼說明可以供給,否則只能內銷

(3).2的程式碼

if(vac.size()-3<n+1-(vac[i]-vac[i-2]))
ans=max(ans,vac[i]-vac[i-2]-1);
else
ans=max(ans,vac[i]-vac[i-2]-2);

完整程式碼

#include <bits/stdc++.h>
using namespace std;
vector<int> vac;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,ans=-1;
  cin>>n;
  string a;
  cin>>a;
  vac.push_back(0);
  for(int i=0;i<a.size();i++)
  if(a[i]=='S')
  vac.push_back(i+1);
  vac.push_back(n+1);
  if(vac.size()==2)
  cout<<n;
  else if(vac.size()==3)
  cout<<n-1;
  else
  {
    for(int i=2;i<vac.size();i++)
    {
      if(vac.size()-3<n+1-(vac[i]-vac[i-2]))
      ans=max(ans,vac[i]-vac[i-2]-1);
      else
      ans=max(ans,vac[i]-vac[i-2]-2);
    }
    cout<<ans;
  }
}