赞
踩
解题思路
贪心题,Alice和Bob为了处理字典序,必定是从开头遍历字符串的。作为Alice想要最小,那么就将当前所处理的字符变为’a’,要注意,如果当前处理字符串就为’a’,那么Alice需要将其变为’b’。同理Bob想要最大,那么就就将所处理的字符变为’z’,要注意,如果当前处理字符串就为’z’,那么Bob需要将其变为’y’。
AC代码
/** *@filename:A_Yet_Another_String_Game *@author: pursuit *@csdn:unique_pursuit *@email: 2825841950@qq.com *@created: 2021-07-01 16:40 **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000 + 5; const int P = 1e9+7; int t; string s; void solve(){ //Alice want to be min,Bob want to be max, Alice first; bool flag = true; for(auto &x : s){ if(flag){ //让其最小。 if(x == 'a'){ x = 'b'; } else{ x = 'a'; } } else{ //让其最大。 if(x == 'z'){ x = 'y'; } else{ x = 'z'; } } flag = !flag; } cout << s << endl; } int main(){ cin >> t; while(t -- ){ cin >> s; solve(); } return 0; }
/** *@filename:B_The_Great_Hero *@author: pursuit *@csdn:unique_pursuit *@email: 2825841950@qq.com *@created: 2021-07-01 16:46 **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000 + 5; const int P = 1e9+7; int t,n; ll A,B,a[N],b[N]; ll maxx; void solve(){ bool flag = false; for(int i = 1; i <= n; ++ i){ int temp = b[i] / A + (b[i] % A != 0); B -= a[i] * temp; } B += maxx; if(B <= 0)flag = true; printf("%s\n",flag ? "NO" : "YES"); } int main(){ scanf("%d", &t); while(t -- ){ maxx = 0; scanf("%lld%lld%d", &A, &B, &n); for(int i = 1; i <= n; ++ i){ scanf("%lld", &a[i]); maxx = max(a[i],maxx);//存储其中的最大伤害。 } for(int i = 1; i <= n; ++ i){ scanf("%lld", &b[i]); } solve(); } return 0; }
解题思路
我们需要找到一个局部最小值下标
i
i
i,即
a
i
−
1
>
a
i
<
a
i
+
1
a_{i-1}>a_i<a_{i + 1}
ai−1>ai<ai+1。数据范围为
1
0
5
10^5
105,查询次数不能超过
100
100
100次。所以我们应该能想到二分。怎么二分呢?数组不是无序的嘛?数组虽然是无序的,可是我们可以维护一个区间
[
l
,
r
]
[l,r]
[l,r],使得其中存在局部最小值,同时我们保证
a
l
−
1
>
a
l
,
a
r
<
a
r
+
1
a_{l-1}>a_l,a_r<a_{r+1}
al−1>al,ar<ar+1。那么我们每次二分取中点
m
m
m,然后查询
a
m
,
a
m
+
1
a_m,a_{m+1}
am,am+1,如果
a
m
<
a
m
+
1
a_m<a_{m+1}
am<am+1,为了维护这个区间,即区间变成
[
l
,
m
]
[l,m]
[l,m];同理,如果
a
m
>
a
m
+
1
a_m>a_{m + 1}
am>am+1,为了维护这个区间,即区间变成
[
m
+
1
,
r
]
[m+1,r]
[m+1,r]。我们这样维护下去,最后当区间长度为
1
1
1的时候必定是局部最小值。
AC代码
/** *@filename:C_Searching_Local_Minimum *@author: pursuit *@csdn:unique_pursuit *@email: 2825841950@qq.com *@created: 2021-07-02 08:36 **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000 + 5; const int P = 1e9+7; int n,l,r; int get(int idx){ cout << "? " << idx << endl; fflush(stdout); int res; cin >> res; return res; } void solve(){ l = 1,r = n; while(l < r){ int mid = l + r >> 1; int temp1 = get(mid + 1),temp2 = get(mid); if(temp2 < temp1){ //说明左边小于右边。那么答案就在左边。 r = mid; } else{ l = mid + 1; } } cout << "! " << l << endl; fflush(stdout); } int main(){ cin >> n; solve(); return 0; }
给你一个序列 a,请你将这个序列撕开分成两个序列 a ( 0 ) a^{(0)} a(0)和 a ( 1 ) a^{(1)} a(1) ,使得将 a ( 0 ) a^{(0)} a(0)和 a ( 1 ) a^{(1)} a(1)合并所有相邻且相同的元素之后,两个序列剩余的元素个数和最大。
解题思路
此题我们可以贪心实现。我们来分析一下,对于这两个序列,影响放置的决定因素就是当前序列中的最后一个元素,我们设
a
(
0
)
a^{(0)}
a(0)的最后一个元素为
x
x
x,
a
(
1
)
a^{(1)}
a(1)的最后一个元素为
y
y
y。那么对于当前要放置的元素
z
1
z_1
z1来看,我们分类讨论:
经过以上分析,此题也就迎刃而解了,我们遍历处理即可。
AC代码
/** *@filename:D1_Painting_the_Array_I *@author: pursuit *@csdn:unique_pursuit *@email: 2825841950@qq.com *@created: 2021-07-02 09:00 **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000 + 5; const int P = 1e9+7; int n,a[N]; void solve(){ int ans = 0; int x = -1,y = -1;//x代表a0中的最后一个元素,y代表a1中的最后一个元素,初始化为-1. for(int i = 1; i <= n; ++ i){ int z1 = a[i],z2 = a[i + 1];//z1表示当前要处理的元素,z2表示下一个要处理的元素。 if(z1 == x && z1 == y)continue;//因为放哪都没有贡献。 if(z1 == x){ //此时放a1更优。 ans ++; y = z1; } else if(z1 == y){ //此时放a0更优。 ans ++; x = z1; } else{ //如果两个都可以放,我们需要考虑贡献,即下一个元素是否会影响。 ans ++; if(z2 == x){ //那我们放x就可能抵消这种冲突。 x = z1; } else{ y = z1; } } } cout << ans << endl; } int main(){ scanf("%d", &n); for(int i = 1; i <= n; ++ i){ scanf("%d", &a[i]); } solve(); return 0; }
给你一个序列 a,请你将这个序列撕开分成两个序列 a ( 0 ) a^{(0)} a(0)和 a ( 1 ) a^{(1)} a(1) ,使得将 a ( 0 ) a^{(0)} a(0)和 a ( 1 ) a^{(1)} a(1)合并所有相邻且相同的元素之后,两个序列剩余的元素个数和最小。**
/** *@filename:D1_Painting_the_Array_I *@author: pursuit *@csdn:unique_pursuit *@email: 2825841950@qq.com *@created: 2021-07-02 09:00 **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 100000 + 5; const int P = 1e9+7; int n,a[N]; vector<int> v[N]; int nex[N]; void solve(){ for(int i = 1; i <= n; ++ i){ for(int j = 0 ; j < (int)v[i].size() - 1; ++ j){ nex[v[i][j]] = v[i][j + 1];//保存下一个与其值相等的情况。 } } int ans = 0; int x = -1,y = -1;//x代表a0中的最后一个元素,y代表a1中的最后一个元素,初始化为-1. int next_x = n + 1,next_y = n + 1;//初始化。 for(int i = 1; i <= n; ++ i){ int z1 = a[i],z2 = a[i + 1];//z1表示当前要处理的元素,z2表示下一个要处理的元素。 if(z1 == x){ //放x更优。 next_x = nex[i]; } else if(z1 == y){ next_y = nex[i]; } else{ //说明都不相等,我们需要考虑放哪个更优。 ans ++; if(z2 == x && z2 != y){ y = z1; next_y = nex[i]; } else if(z2 == y && z2 != x){ x = z1; next_x = nex[i]; } else{ if(next_x < next_y){ //说明下个相等的x比y先到。 y = z1; next_y = nex[i]; } else{ x = z1; next_x = nex[i]; } } } } cout << ans << endl; } int main(){ scanf("%d", &n); for(int i = 1; i <= n; ++ i){ scanf("%d", &a[i]); v[a[i]].push_back(i); nex[i] = n + 1; } solve(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。