# 补题
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;
}