飞机直达
A - Beautiful String
题意思路略
#include <bits/stdc++.h>
using namespace std;
int vis[4];
int main()
{
int t;
cin >> t;
while(t --){
string s;
cin >> s;
int flag = 0;
for(int i = 0; i < s.size(); i ++){
if(i + 1 < s.size() &&s[i] == s[i + 1] && s[i] != '?'){
flag = 1;
break;
}
if(s[i] == '?'){
memset(vis, 0 ,sizeof vis);
if(i != 0){
vis[s[i - 1] - 'a'] ++;
}
if(i + 1 < s.size() && s[i + 1] != '?'){
vis[s[i + 1] - 'a']++;
}
for(int j = 0 ; j< 3; j ++){
if(!vis[j]){
s[i] = char(j + 'a');
break;
}
}
}
}
if(flag) cout << -1 << endl;
else
cout << s << endl;
}
}
B - Beautiful Numbers
题意思路略
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int x, y;
}a[200005];
bool cmp(node a,node b){
return a.x < b.x;
}
int vis[200005];
signed main()
{
int t;
cin >> t;
while(t --){
memset(vis, 0, sizeof vis);
int n;
cin >> n;
for(int i = 1; i <= n; i ++){
cin >> a[i].x;
a[i].y = i;
}
sort(a + 1 , a + n + 1, cmp);
int minx = INT_MAX, maxn = -INT_MAX;
for(int i = 1; i <= n;i ++){
if(i == 1){
minx = min(minx, a[i].y);
maxn = max(maxn, a[i].y);
vis[i] = 1;
}
else {
minx = min(minx, a[i].y);
maxn = max(maxn, a[i].y);
if(maxn - minx < i){
vis[i] = 1;
}
else vis[i] = 0;
}
}
vis[n] = 1;
for(int i = 1; i <= n; i ++){
cout << vis[i];
}
cout << endl;
}
}
C - Beautiful Regional Contest
题意思路略
#include <bits/stdc++.h>
using namespace std;
int a[1000005];
int num[1000005];
int len = 1;
int n;
int main()
{
int t;
cin >> t;
while(t --){
memset(num, 0, sizeof num);
cin >> n;
for(int i = 1;i <= n; i ++){
cin >> a[i];
}
if(n < 6){
for(int i = 0 ;i < 3; i ++){
cout << 0 <<" ";
}
cout << endl;
}
else{
len = 1;
num[len] = 1;
for(int i = 1; i <= n;){
int j = i + 1;
while(j <= n && a[j] == a[i]) num[len] ++, j ++;
i = j;
len ++;
num[len] = 1;
}
int mg = 0, ms = 0, mk = 0;
mg = num[1];
for(int i = 2; i < len; i ++){
if(ms <= mg) ms += num[i];
else if(mk <= mg) mk += num[i];
else if(mg < ms && mg < mk){
if(mg + ms + mk + num[i] <= n/2){
mk += num[i];
}
else break;
}
}
if(mg + ms + mk <= n/2){
cout << mg <<" " << ms <<" " << mk << endl;
}
else cout << 0 <<" " << 0 << " " << 0 << endl;
}
}
}
D - Beautiful Sequence
模拟
模拟也有技巧
双端队列直接放就行
#include <bits/stdc++.h>
using namespace std;
std::vector<int> v;
int main()
{
int a,b,c,d;
cin >> a >> b >> c >> d;
if(a + b + c+ d == 1){
cout <<"YES" << endl;
if(a) cout << 0 << endl;
if(b) cout << 1 << endl;
if(c) cout << 2 << endl;
if(d) cout << 3 << endl;
return 0;
}
int n = a+ b+ c+d;
deque<int> q;
for(int i = 0; i < n; i ++){
if(a){
if(q.empty()){
q.push_back(0);
a --;
continue;
}
if(q.front() == 1){
q.push_front(0);
a --;
continue;
}
if(q.back() == 1){
q.push_back(0);
a --;
continue;
}
}
if(b){
if(q.empty()){
q.push_back(1);
b --;
continue;
}
if(q.front() == 0){
q.push_front(1);
b --;
continue;
}
if(q.back() == 0){
q.push_back(1);
b --;
continue;
}
if(q.front() == 2){
q.push_front(1);
b --;
continue;
}
if(q.back() == 2){
q.push_back(1);
b --;
continue;
}
}
if(c){
if(q.empty()){
q.push_back(2);
c --;
continue;
}
if(q.front() == 1){
q.push_front(2);
c --;
continue;
}
if(q.back() == 1){
q.push_back(2);
c --;
continue;
}
if(q.front() == 3){
q.push_front(2);
c --;
continue;
}
if(q.back() == 3){
q.push_back(2);
c --;
continue;
}
}
if(d){
if(q.empty()){
q.push_back(3);
d --;
continue;
}
if(q.front() == 2){
q.push_front(3);
d --;
continue;
}
if(q.back() == 2){
q.push_back(3);
d --;
continue;
}
}
cout <<"NO" << endl;
return 0;
}
cout <<"YES" << endl;
while(!q.empty()){
cout << q.front()<<" ";
q.pop_front();
}
cout << endl;
}
E - Beautiful Mirrors
期望dp
考虑dp[i]表示
1
−
i
1 - i
1−i 的期望
那么
d
p
[
i
]
=
(
1
+
d
p
[
i
−
1
]
)
∗
p
(
成
功
)
+
(
1
+
d
p
[
i
−
1
]
+
d
p
[
i
]
)
∗
p
(
失
败
)
dp[i] = (1 + dp[i - 1])*p(成功) + (1 + dp[i - 1] + dp[i])*p(失败)
dp[i]=(1+dp[i−1])∗p(成功)+(1+dp[i−1]+dp[i])∗p(失败)走到第i位是从i - 1 过来的,所以如果当前位成功那么直接加1乘上成功的概率,如果当前失败的话,那么当前已经用了
1
+
d
p
[
i
−
1
]
1 + dp[i - 1]
1+dp[i−1]步再走回来还要
d
p
[
i
]
dp[i]
dp[i]步,所以一共是
1
+
d
p
[
i
−
1
]
+
d
p
[
i
]
1 + dp[i - 1] + dp[i]
1+dp[i−1]+dp[i]
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
typedef long long ll;
ll quick(ll a, ll b){
ll ans = 1;
while(b){
if(b&1){
ans = ans * a%mod;
}
b >>= 1;
a = a*a%mod;
}
return ans;
}
int main()
{
ll ans = 0;
int n;
cin >> n;
for(int i = 1; i <= n; i ++){
ll x;
cin >> x;
ans = (ans + 1)%mod;
ans = ans*100%mod*(quick(x , mod - 2))%mod;
}
cout << ans << endl;
}
这道题div1 有个加强版的
给了q次查询把每次给一个位置pos表示这个位置之后,还出现失败的话返回到pos上而不是1上。
如果还是用上面的期望dp就不好弄了。
思路参看这个视频大佬真滴强
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
int p[200005];
int sp[200005];
int tp[200005];
int quick(int a, int b){
int ans = 1;
while(b){
if(b&1){
ans = a*ans% mod;
}
b >>= 1;
a = a*a%mod;
}
return ans;
}
int query(int l, int r){
if(l == 1){
int ans = (tp[r - 1] + 1)%mod*quick(sp[r],mod - 2)%mod;
return ans;
}
int ans = (tp[r - 1] - tp[l - 2] + mod)%mod*quick(sp[r], mod - 2)%mod;
return ans;
}
signed main()
{
int n,q;
cin >> n >> q;
sp[0] = 1;
for(int i = 1;i <= n;i ++){
cin >> p[i];
p[i] = p[i]*quick(100,mod -2)%mod;
sp[i] = sp[i - 1]*p[i]%mod;
tp[i] = (tp[i - 1] + sp[i])%mod;
}
set<int> st;
st.insert(1);
st.insert(n + 1);
int ans = (tp[n - 1] + 1)%mod*quick(sp[n],mod-2)%mod;
while(q --){
int x;
cin >> x;
if(st.find(x) != st.end()){
st.erase(x);
auto pos = st.lower_bound(x);
int r = *(pos) - 1;
int l = *(--pos);
ans = (ans - query(l, x - 1) + mod)%mod;
ans = (ans - query(x , r) + mod)%mod;
ans = (ans + query(l, r))%mod;
}
else {
auto pos = st.lower_bound(x);
int r = *(pos) - 1;
int l = *(--pos);
ans = (ans - query(l , r) + mod)%mod;
ans = (ans + query(l, x - 1))%mod;
ans = (ans + query(x, r))%mod;
st.insert(x);
}
cout << ans << endl;
}
}