Neowise Labs Contest 1 (Codeforces Round 1018, Div. 1 + Div. 2)(A~E)

# 补题

A. Wonderful Sticks

题目:

思路:

从左到右,存一下该位置左边最大和最小,如果当前位置是'>'那么下一个位置就是mx+1,'<'就是mi-1,最后在处理一下让数组满足每一个数∈(1,n)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	int n;cin>>n;
	string s;cin>>s;
	vector<int> a(n);
	int  mx=100;
	int mi=100;
	a[0]=100;
	for(int i=0;i<s.size();i++){
		mi=min(mi,a[i]);
		mx=max(mx,a[i]);
		if(s[i]=='<')a[i+1]=mi-1;
		else a[i+1]=mx+1;
		if(i==s.size()-1){
			mi=min(mi,a[i+1]);
			mx=max(mx,a[i+1]);
		}
	}
	for(auto it:a)cout<<it-mi+1<<" ";cout<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _;cin>>_;
	while(_--)solve();
	return 0;
}

B. Wonderful Gloves

题目:

思路:

考虑最坏的情况,先加上max(l[i],r[i]),然后对于min(l[i],r[i])组成的数组进行排序,然后取最大的k-1个,然后在+1就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	int n,k;cin>>n>>k;
	vector<int> l(n+1);
	vector<int> r(n+1);
	ll sm=0;
	for(int i=1;i<=n;i++)cin>>l[i];
	for(int i=1;i<=n;i++)cin>>r[i];
	vector<int> t;
	for(int i=1;i<=n;i++){
		sm+=max(l[i],r[i]);
		t.push_back(min(l[i],r[i]));
	}
	sort(t.begin(),t.end());
	ll t1=0;
	for(int i=n-1;i>n-1-k+1;i--){
		t1+=t[i];
	}
	cout<<sm+t1+1<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _;cin>>_;
	while(_--)solve();
	return 0;
}

C. Wonderful City

题目:

思路:

首先可以发现它的的行和列是独立的,比如1 1,不管怎样选择a数组,这两个位置的数还是会相等。所以分别对行列使用一次dp就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll n;cin>>n;
	vector<vector<ll>> h(n+1,vector<ll> (n+1));
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=n;j++)cin>>h[i][j];
	}
	vector<ll> a(n+1);
	vector<ll> b(n+1);
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	vector<vector<ll>> dp1(n+1,vector<ll> (2,inf));
	ll res1=inf;
	dp1[1][1]=a[1];
	dp1[1][0]=0;
	for(ll i=1;i<n;i++){
		for(ll j1=0;j1<2;j1++){
			for(ll j2=0;j2<2;j2++){
				for(ll k=1;k<=n;k++){
					ll t1=h[i][k];
					ll t2=h[i+1][k];
					ll add=0;
					if(j1)t1++;
					if(j2)t2++,add+=a[i+1];
					if(t1==t2)break;
					if(k==n){
						dp1[i+1][j2]=min(dp1[i+1][j2],dp1[i][j1]+add);
					}
				}
			}
		}
	}
	res1=min(dp1[n][0],dp1[n][1]);
	ll res2=inf;
	vector<vector<ll>> dp2(n+1,vector<ll> (2,inf));
	dp2[1][0]=0;dp2[1][1]=b[1];
	for(ll i=1;i<n;i++){
		for(ll j1=0;j1<2;j1++){
			for(ll j2=0;j2<2;j2++){
				for(ll k=1;k<=n;k++){
					ll t1=h[k][i];
					ll t2=h[k][i+1];
					ll add=0;
					if(j1)t1++;
					if(j2)t2++,add+=b[i+1];
					if(t1==t2)break;
					if(k==n){
						dp2[i+1][j2]=min(dp2[i+1][j2],dp2[i][j1]+add);
					}
				}
			}
		}
	}
	res2=min(dp2[n][0],dp2[n][1]);
	if(res1==inf||res2==inf)cout<<-1<<endl;
	else cout<<res1+res2<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
	return 0;
}

D. Wonderful Lightbulbs

题目:

思路:

通过题目可以观察到对一个点操作后的影响,可以发现假如图中的x,y是最开始的灯,那么无论后面怎样操作直线,L1,L2,上的灯的数量一定是奇数个,所以只需要求出满足条件的直线,然后他们的交点就是答案。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll n;cin>>n;
	map<ll,ll> dx,dxy;
	for(ll i=0;i<n;i++){
		ll x,y;cin>>x>>y;
		dx[x]++;
		dxy[x+y]++;
	}
	ll ansx,ansxy;
	for(auto it:dx){
		if(it.second%2)ansx=it.first;
	}
	for(auto it:dxy){
		if(it.second%2)ansxy=it.first;
	}
	cout<<ansx<<" "<<ansxy-ansx<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
	return 0;
}

E. Wonderful Teddy Bears

题目:

思路:

由题目我们知道我们每一次可以对三个连续的字符进行操作,然后我们可以可以发现,对于一个B,或者P它一次性走两步一定是比较好的,比如PBB->BBP,或者PPB->BPP,所以我们对于哪些BB或者PP我们可以优先移到左边或者右边,然后就会剩下PBPBPB......PB,此时如果有奇数个PB就拿去一个,其它的变成BBPPBBPP .....然后这里其实就是一个等差数列求和(PBPB->BBPP要两次操作别忘了加),最后再把PB里面的B移过去就行了。偶数就一样不过没有剩的PB。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll n;cin>>n;
	string s;cin>>s;
	s="#"+s;
	ll ans=0;
	ll cnt_p=0;
	ll t=0;
	stack<char> stk;
	for(ll i=1;i<=n;i++){
		if(s[i]=='B'){
			if(stk.size()){
				if(stk.top()=='B'){
					ans+=stk.size()/2;
					stk.pop();
				}else{
					stk.push('B');
				}
			}
			ans+=cnt_p;
		}else{
			if(stk.size()){
				if(stk.top()=='P'){
					cnt_p+=1;
					stk.pop();
				}else{
					stk.push('P');
				}
			}else{
				stk.push('P');
			}
		}
	}
	ll add=0;
	if(stk.size()){
		if(stk.top()=='P')stk.pop();
		ll t=stk.size()/2;
		if(t){
			if(t%2){
				t--;
				t/=2;
				add+=t*2+t*(t-1)+(stk.size()/2+1)/2;	
			}else{
				t/=2;
				add+=t*2+t*(t-1);
			}
		}
	}
	cout<<ans+add<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值