Educational Codeforces Round 101 (Rated for Div. 2)
題目連結:https://codeforces.com/contest/1469
A.Regular Bracket Sequence
題目大意:給你含有一個( 和一個 ),其他全是 ?的字串,判斷該字串是否合法
題目思路:特判:①如果開頭 )結尾( ,不合法②如果 ? 的個數是奇數,不合法
AC程式碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <map> #include <string> #include <cstring> #include <set> #include <stack> #include <deque> #include <queue> using namespace std; typedef pair<int, int> PII; typedef long long ll; typedef pair<double, double> PDD; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const int N = 110, M = 4 * N; const int base = 1e9; const int P = 131; int n, m, t, k; int main() { scanf("%d", &t); while (t--) { string s; cin >> s; int len = s.size(); if (s[0] == ')' || s[len - 1] == '(') printf("No\n"); else if (s.size() % 2 == 0) printf("Yes\n"); else printf("No\n"); } return 0; }
B.Red and Blue
題目大意:給你兩個陣列a,b,不改變元素的先後順序,構造陣列c,使陣列c字首和的最大值最大
題目思路:求陣列a,b字首的最大值,可能這些最大值也小於0
AC程式碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <map> #include <string> #include <cstring> #include <set> #include <stack> #include <deque> #include <queue> using namespace std; typedef pair<int, int> PII; typedef long long ll; typedef pair<double, double> PDD; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const int N = 110, M = 4 * N; const int base = 1e9; const int P = 131; int n, m, t, k; int main() { scanf("%d", &t); while (t--) { int max1 = -INF, max2 = -INF; int sum1 = 0, sum2 = 0; scanf("%d", &n); for (int i = 1; i <= n; ++i) //求陣列a字首和最大值 { int x; scanf("%d", &x); sum1 += x; max1 = max(max1, sum1); } scanf("%d", &m); for (int i = 1; i <= m; ++i) //求陣列b字首和最大值 { int x; scanf("%d", &x); sum2 += x; max2 = max(max2, sum2); } //可能max1或者max2小於0,需特判 printf("%d\n", max(0, max(max1 + max2, max(max1, max2)))); } return 0; }
C.Building a Fence
題目大意:給你一堆高度去建圍欄,這些圍欄必須有公共邊,第一個和最後一個圍欄必須挨著地面,其他圍欄可以浮空,但不能超過k - 1
題目思路:依次處理每個圍欄的區間,假設圍欄所在區間最低為low,最高為high,則第一個圍欄low = h[1], high = h[1] + k,第二個圍欄low = max(low - k + 1, h[i]),因為每個區間需要有公共邊,所以max裡第二個值還需 + 1,high = min(high + k - 1, h[i] + 2 * k - 1),第一個區間最大值 + 圍欄高度 - 1),因為圍欄最多浮空k - 1,所以max裡第一個值為地面高度 + k - 1 + k,因為每個區間需要有公共邊,所以max裡第二個值還需 - 1,以此類推。
如果在此期間,出現以下4種情況,則圍欄構建失敗:①區間最大值 - 圍欄高度 < 地面高度,②區間最小值 > 地面高度 + k - 1,③區間最大值 < 區間最小值,④最後一個區間最小值 ≠ 最後一個地面高度
AC程式碼:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <stack>
#include <deque>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
typedef pair<double, double> PDD;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10, M = 4 * N;
const int base = 1e9;
const int P = 131;
int n, m, t, k;
int h[N];
int main()
{
scanf("%d", &t);
while (t--)
{
int flag = 1;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i)
scanf("%d", &h[i]);
int low = h[1], high = h[1] + k; //圍欄所處區間[low, high]
for (int i = 2; i <= n; ++i)
{
high = min(high + k - 1, h[i] + 2 * k - 1); //處理最大值
low = max(low - k + 1, h[i]); //處理最小值
if (high - k < h[i] || low > h[i] + k - 1 || high < low) //不符合條件的情況
{
flag = 0;
break;
}
}
if (low != h[n]) //如果最後不接地
flag = 0;
if (flag == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
D.Ceil Divisions
題目大意:給你至多n + 5步,通過以下操作將給定的陣列處理成含有 n - 1 個 1 和 1 個 2 的陣列
操作:取兩個指標x,y 使 \(a_x = \left\lceil \frac{a_x}{a_y} \right\rceil\) \(\left\lceil x \right\rceil\)是向上取整
題目思路:以n為 2e5 為例,對 2e5 反覆開根號操作得下圖中的數,稱為根號數
從圖可知,將 2e5 變為 1 只需 2 步,即輸出 200000 448 20000 448,對 448 同理,輸出 448 22 448 22,從而最多隻需 10 步就可將圖中幾個數變為 1(保留2)
首先遍歷,將所有不是上圖的數輸出 i 2e5,保留上圖中的數,實際上保留了 7 個數字(包括1),所以用了 n - 7 步,在加上上述的10步,可知 n 為 2e5 時最多需要 n + 3 步,其它都比 2e5 的情況小,假設根號數有 k 個,則 總步數為 (n - k - 1) + (2 *(k - 1)) = n + k - 3 步
AC程式碼:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <stack>
#include <deque>
#include <queue>
#include <cmath>
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
typedef pair<double, double> PDD;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10, M = 4 * N;
const int base = 1e9;
const int P = 131;
int n, m, t, k;
map<int, int> mp;
int a[10];
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
mp.clear();
int pos = 0;
k = n;
mp[n] = 1; //預處理根號數
a[++pos] = n;
while (k > 2)
{
double g = sqrt(k);
if (g - (int)g == 0) //如果能除盡則不需要向上取整
a[++pos] = g;
else
a[++pos] = g + 1;
mp[a[pos]] = 1;
k = a[pos];
}
printf("%d\n", n + pos - 3); //輸出步數
for (int i = 2; i <= n; ++i)
if (mp[i] == 0)
printf("%d %d\n", i, n); //遍歷輸出i n
for (int i = 1; i < pos; ++i) //輸出根號數
{
printf("%d %d\n", a[i], a[i + 1]);
printf("%d %d\n", a[i], a[i + 1]);
}
}
return 0;
}