Codeforces Round #604 (Div. 2)

飞机直达
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 1i 的期望
那么 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[i1])p()+(1+dp[i1]+dp[i])p()走到第i位是从i - 1 过来的,所以如果当前位成功那么直接加1乘上成功的概率,如果当前失败的话,那么当前已经用了 1 + d p [ i − 1 ] 1 + dp[i - 1] 1+dp[i1]步再走回来还要 d p [ i ] dp[i] dp[i]步,所以一共是 1 + d p [ i − 1 ] + d p [ i ] 1 + dp[i - 1] + dp[i] 1+dp[i1]+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;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值