0%

Codeforces Round #674 (Div.3)

這週一沒有打這場比賽 因為時間實在是沒有辦法打 இдஇ

今天突然想到 就決定來Virtual一下了

打完之後覺得自己真的是太久沒有打 Div.3 了

這種Ad-Hoc的題目都要想很久才會解

Problem A - Floor Number


還沒看題目 看到範測 直接砸了 $\lceil \frac{n}{x} \rceil$

然後就WA了 (☍﹏⁰)

看了題目才知道 他是第一樓只能住 $2$ 個人

所以改成 $\lfloor \frac{n}{x} \rfloor+2$ 然後特判 $n \leq 2$ 就過了

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>

#define int long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

void solve(){
int n,x;
cin >> n >> x;
cout << (n<= 2 ? 1 : (n-3)/x+2) << "\n";
}

signed main(){
fastio
int t = 1;
cin >> t;
while(t--) solve();
}

Problem B - Symmetric Matrix

題目很長 不太想讀

不過意思是他會給 $n$ 個 $2\times2$ 的矩陣無限多個

問是否能排出 $m \times m$ 對稱對角線的矩陣

這題有兩個條件

第一個是 $m$ 要是二的倍數

第二個是至少一個矩陣的右上和左下要相等

這兩個條件符合就過了

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>

#define int long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

void solve(){
int n,m;
cin >> n >> m;
bool ok = false;
for(int i = 0;i < n;i++){
int a,b,c,d;
cin >> a >> b >> c >> d;
if(b==c){
ok = true;
}
}
if(m%2) ok = false;
cout << (ok ? "YES\n" : "NO\n");
}

signed main(){
fastio
int t = 1;
cin >> t;
while(t--) solve();
}

Problem C - Increase And Copy

看著題目想了一下子 一直都沒有想法

不過仔細想過之後會發現

要達到最好的解一定是先增加之後再一併複製

因此我們只要一直對一開始的 $1$ 去加 $1$

最後再乘以一個數字就好了

我們可以用枚舉的方式達到這一點

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>

#define int long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

void solve(){
int n;
cin >> n;
int ans = INT_MAX;
for(int i = 0;i <= sqrt(1e9);i++){
int tmp = (n-1)/(i+1);
ans = min(ans,tmp+i);
}
cout << ans << "\n";
}

signed main(){
fastio
int t = 1;
cin >> t;
while(t--) solve();
}

Problem D - Non-zero Segment

這題看到題目 就會想到要用前綴和 (使區間和不等於 $0$)

區間和為 $0$ 的狀況就是有兩個前綴和值相等

而我們要加幾次才能讓前綴和兩兩不相等呢

仔細想一下 會發現如果我們每次都加一個非常非常大的值

沒有加到這個值的前綴和一定不會和後面相等

所以我們只要在相等的時候 重置 map 的值就好

然後當前綴和為 $0$ 的時候也要重製 map

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>

#define int long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

signed main(){
fastio
int n;
cin >> n;
map<int,int> m;
int now = 0, ans = 0;
m[0] = 1;
for(int i = 0;i < n;i++){
int tmp;
cin >> tmp;
now+=tmp;
if(m[now]){
m.clear();
ans++;
now = tmp;
m[0]++;
}
m[now]++;
}
cout << ans << "\n";
}

Problem E - Rock, Paper, Scissors

這題的話就是兩個人剪刀石頭布

其實想一下很快就解出來了

不知道為什麼會放這種題在pE (*´・д・)?

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <bits/stdc++.h>

#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

signed main(){
fastio
int n;
cin >> n;
int a,b,c,d,e,f;
cin >> a >> b >> c >> d >> e >> f;
cout << min(max(0,a-d-f),e)+min(max(0,b-e-d),f)+min(max(0,c-f-e),d) <<" " << min(a,e)+min(b,f)+min(c,d);
}

Problem F - Number of Subsequences

總算不是 Ad-Hoc 題了 前面幾題都是 Ad-Hoc 超痛苦

這題一看到 就知道要使用 dp 來解了

所以就列出轉移式 然後就 AC 了

複雜度: $O(n)$

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>

#define int long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;

const int MOD = 1e9+7;

signed main(){
fastio
int n;
cin >> n;
string s;
cin >> s;
int dp[n][3] = {}, cnt = 1;
for(int i = 0;i < n;i++){
if(s[i]=='a'){
dp[i][0] = (dp[i][0] + cnt)%MOD;
}else if(s[i]=='b'){
if(i>0)
dp[i][1] = (dp[i][1] + dp[i-1][0])%MOD;
}else if(s[i]=='c'){
if(i>0)
dp[i][2] = (dp[i][2] + dp[i-1][1])%MOD;
}else{
dp[i][0] = (dp[i][0]*3 + cnt)%MOD;
if(i>0)
dp[i][1] = (dp[i][1]*3 + dp[i-1][0])%MOD;
if(i>0)
dp[i][2] = (dp[i][2]*3 + dp[i-1][1])%MOD;
cnt = cnt*3%MOD;
}
if(i!=n-1){
dp[i+1][0] = dp[i][0];
dp[i+1][1] = dp[i][1];
dp[i+1][2] = dp[i][2];
}
}
cout << dp[n-1][2] << "\n";
}