1. 程式人生 > >Educational Codeforces Round 58 (Rated for Div. 2) (前兩題題解)

Educational Codeforces Round 58 (Rated for Div. 2) (前兩題題解)

感慨

這次比較昏迷最近演算法有點飄,都在玩pygame。。。做出第一題讓人hack了,第二題還昏迷想錯了

A Minimum Integer(數學)

水題,上來就能做出來但是讓人hack成了tle,所以要思考一下具體的過程

原本我是認為直接把d進行累加看什麼時候不在那個segment內也就是那個範圍之內結果tle

今天思考一下發現有兩種情況

①如果d本來就是小於左邊界的那麼就輸出d就可以了,因為樣例明確提示有原來的數也可以

②然後就是如果d在範圍之內或者範圍外可以用餘數來確定具體的數公式是:

ans=r+d-r%d

如何說明其正確性呢?

首先AC了(。。。。)

其次先說明如果d大於r那麼這個公式輸出d沒有任何問題

然後再說明特例d在segment內,那麼ans一定大於r,要找最小的ans那麼就需要找離r最小的數,所以先餘數餘一下看看ans距離r的一個距離然後再用特例去驗證一下發現了這個公式成立(這也不算證明。。。)

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  while(n--)
  {
    int l,r,d;
    cin>>l>>r>>d;
    if(d<l)
    cout<<d<<"\n";
    else
    {
      int k=r%d;
      cout<<r+d-k<<"\n";
    }
  }
}

B Accordion(字串模擬)

昨天昏迷了忘記了一個右括號可以包含的問題今天上來藉助著資料的力量把這個題A了,這個題資料就有進600組。。。還是模擬題著實是一道不錯的題,很考驗細節能力

首先按照特例先說一下-1的情況

(1)-1的情況

①沒有出現左括號

②沒有出現右括號

③兩個括號中間的冒號少於兩個

接著說一下具體的判定的思路實現自己來或者看程式碼

(2)最大值的計算

①首先要想一下什麼時候會出現最大值那麼不就是要在最大的兩個合法的冒號內有最多的豎線嗎?這個合法又是什麼意思?

合法的意思就是兩個冒號外面還有兩個相應的閉合的中括號。所以有了思路我們的目標就明確了

就是去找合法的最大的冒號區域以及其中的豎線最後的答案就是4+區域內豎線的個數

程式碼

#include <bits/stdc++.h>
using namespace std;
int bk1[666666],bk2[666666],bk3[666666],bk4[666666],p1,p2,p3,p4,ans,sum,rt;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  string a;
  cin>>a;
  for(int i=0;i<a.size();i++)
  {
    if(a[i]=='[')
    bk1[p1++]=i;
    if(a[i]==':')
    bk2[p2++]=i;
    if(a[i]==']')
    bk3[p3++]=i;
  }
  for(int i=0;i<p2;i++)
  if(bk2[i]>bk1[0]&&bk2[i]<bk3[p3-1])
  ans++,bk4[p4++]=bk2[i];
  if(ans<2||p1==0||p3==0)
  return cout<<-1,0;
  for(int i=p3-1;i>=0;)
  {
    if(bk4[p4-1]<bk3[i])
    {
      rt=bk4[p4-1];
      break;
    }
    else
    p4--;
  }
  for(int i=bk4[0];i<rt;i++)
  if(a[i]=='|')
  sum++;
  cout<<4+sum;
}