牛客小白月赛87

小苯的石子游戏

绝顶聪明等于每次都拿最大一堆

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
#include<bits/stdc++.h>
using namespace std;
const int N = 1e2 + 10;
int a[N];
//检查数是否两两相等
bool check(int n)
{
for(int i = 2; i <= n; i += 2)
if(a[i] != a[i - 1])
return false;
return true;
}
int main()
{
int t, n;
cin >> t;
while(t --)
{
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
if(n & 1) cout << "Alice\n";
else
{
if(check(n))
cout << "Bob\n";
else
cout << "Alice\n";
}

}
return 0;
}

小苯的排序疑惑

找出不可能的情况,最小值不在第一位并且最大值不在最后一位,就有问题,不然都可以调整。

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
#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
int a[N];

int main()
{
int t, n;
cin >> t;
while(t --)
{
cin >> n;
int minx = INT_MAX, maxn = INT_MIN;
for(int i = 1; i <= n; i ++)
cin >> a[i];
//找到数组中的最大值和最小值
for(int i = 2; i <= n; i ++)
minx = min(a[i], minx);
for(int i = 1; i < n; i ++)
maxn = max(a[i], maxn);
//判断
if(a[1] > minx && a[n] < maxn)
cout << "NO\n";
else
cout << "YES\n";
}
return 0;
}

小苯的IDE括号问题

阅读好题意就可以开始模拟了

注意,怎么知道到了边界呢,其实可以两头加一个字母

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
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, k;
string s;
int main() {
cin >> n >> k;
cin >> s;
s = "a" + s + "a";
while (k--){
string t;
cin >> t;
int l = s.find("I");
if (t == "backspace") {
if (s[l - 1] == '(' && s[l + 1] == ')') {
s.erase(l + 1, 1);
s.erase(l - 1, 1);
}
else if (s[l - 1] != 'a')
{
s.erase(l - 1, 1);
}
}
else
{
if (s[l + 1] != 'a') {
s.erase(l + 1, 1);
}
}
}
s.erase(0, 1);
s.erase(s.size()-1,1);
cout << s;
return 0;
}

困难版本

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
42
43
44
45
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, k;
string s;
int main()
{
cin >> n >> k;
cin >> s;
s = "a" + s + "a";
while (k--) {
string t;
cin >> t;
int l = s.find("I");
if (t == "backspace")
{
if (s[l - 1] == '(' && s[l + 1] == ')')
{
s.erase(l + 1, 1);
s.erase(l - 1, 1);
}
else if (s[l - 1] != 'a') {
s.erase(l - 1, 1);
}
}
else if(t=="<-")
{
if (s[l - 1] != 'a') swap(s[l - 1], s[l]);
}
else if (t=="->") {
if (s[l + 1] != 'a') swap(s[l + 1], s[l]);
}
else
{
if (s[l + 1] != 'a')
{
s.erase(l + 1, 1);
}
}
}
s.erase(0, 1);
s.erase(s.size() - 1, 1);
cout << s;
return 0;
}

小苯的数组构造

尽量让他相等就行了,这样实际上就满足了极差最小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll a[N], b[N];
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 2; i <= n; i ++)
{
if(a[i] < a[i - 1])
{
b[i] = a[i - 1] - a[i];
a[i] = a[i - 1];
}
}
for(int i = 1; i <= n; i ++)
cout << b[i] << " \n"[i == n];

return 0;
}

小苯的数组拆分

不能都是与运算,因为他对结果是起副作用的

至于或和异或算是有用

不知道哪个更多更好

所以需要处理

进行前缀和处理

至于与运算只需要取最后一位运算即可。

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
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
ll a[N], pre[N], suf[N];
void solve()
{
int n;
cin >> n;
//输入
for(int i = 1; i <= n; i ++)
cin >> a[i];
//前缀异或
for(int i = 1; i <= n; i ++)
pre[i] = pre[i - 1] ^ a[i];
//后缀或
for(int i = n - 1; i >= 1; i --)
suf[i] = suf[i + 1] | a[i];
ll ans = 0;
//比较,取最大
for(int i = 1; i <= n - 2; i ++)
ans = max(ans, pre[i] + suf[i + 1] + a[n]);
cout << ans << '\n';
}

int main()
{
solve();

return 0;
}