codeforces edu 105
A. ABC String
第一个一定是朝右的括号,然后根据匹配来
#include<bits/stdc++.h>
using namespace std;
const int N = 55;
int S[N]={0};
int main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
cin>>str;
n=str.length();
int a=0,b=0,c=0,ff=0,p;
if(str[0]=='A')
ff=1;
else if(str[0]=='B')
ff=2;
else
ff=3;
for(int i=0;i<n;i++)
{
if(str[i]=='A')
{
a++;
}
if(str[i]=='B')
{
b++;
}
if(str[i]=='C')
{
c++;
}
}
int flag=1;
if(a==b+c)
{
p=0;
if(ff==1)
{
for(int i=0;i<n;i++)
{
if(str[i]=='B'||str[i]=='C')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
else
{
for(int i=0;i<n;i++)
{
if(str[i]=='A')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
}
else if(b==a+c)
{
if(ff==2)
{
p=0;
for(int i=0;i<n;i++)
{
if(str[i]=='A'||str[i]=='C')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
else
{
p=0;
for(int i=0;i<n;i++)
{
if(str[i]=='B')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
}
else if(c==a+b)
{
if(ff==3)
{
p=0;
for(int i=0;i<n;i++)
{
if(str[i]=='A'||str[i]=='B')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
else
{
p=0;
for(int i=0;i<n;i++)
{
if(str[i]=='C')
{
p--;
if(p<0)
{
flag=0;
break;
}
}
else
p++;
}
}
}
else
flag=0;
if(flag==1)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
B. Berland Crossword
列举16个状态
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int s[4];
for(int i=0;i<4;i++)
{
cin>>s[i];
}
int flag=0;
for(int a=0;a<2;a++)
{
for(int b=0;b<2;b++)
{
for(int c=0;c<2;c++)
{
for(int d=0;d<2;d++)
{
if(s[0]>=a+b&&s[1]>=b+c&&s[2]>=c+d&&s[3]>=a+d)
{
if(s[0]-a-b<=n-2&&s[1]-b-c<=n-2&&s[2]-c-d<=n-2&&s[3]-a-d<=n-2)
flag=1;
}
}
}
}
}
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
C. 1D Sokoban
负的一边取反之后的处理方式应该和正的方向的处理方式一样,所以只要把正方向的处理就行
之后用lower_bound【大于等于】和upper_bound【大于】可以完成
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int a[N];
int b[N];
map<int, int> mp;
vector<int> v1,v2;
int m,n;
//二分
int solve()
{
mp.clear();
int back=0;
for(int i=0;i<v1.size();i++)
{
int q=v1[i];
mp[q]++;
}
for(int i=v2.size()-1;i>=0;i--)
{
int q=v2[i];
if(mp[q]==1)
back++;
}
// cout<<"back"<<back<<endl;
int ans=back;
for(int i=0;i<v2.size();i++)
{
if(mp[v2[i]])
{
back--;
continue;
}
//某一个点的前面有多少箱子
int number = upper_bound(v1.begin(),v1.end(),v2[i])-v1.begin();
//刚好满足的位置
int pos = lower_bound(v2.begin(),v2.end(),v2[i]-number+1)-v2.begin();
// cout<<"number"<<number<<endl;
// cout<<"pos"<<pos<<endl;
// cout<<"back+i-pos+1: "<<back+i-pos+1<<endl;
ans=max(ans,back+i-pos+1);
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
v1.clear();
v2.clear();
cin>>m>>n;
for(int i=0;i<m;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
cin>>b[i];
}
for(int i=0;i<m;i++)
{
if(a[i]>0)
v1.push_back(a[i]);
}
for(int i=0;i<n;i++)
{
if(b[i]>0)
v2.push_back(b[i]);
}
int ans=solve();
// cout<<"ans"<<ans<<endl;
v1.clear();
v2.clear();
for(int i=m-1;i>=0;i--)
{
if(a[i]<0)
v1.push_back(-a[i]);
}
for(int i=n-1;i>=0;i--)
{
if(b[i]<0)
v2.push_back(-b[i]);
}
ans+=solve();
cout<<ans<<endl;
}
}