本场链接:https://codeforces.com/contest/1494
A. ABC String
https://codeforces.com/contest/1494/problem/A
大意:给出只含有A,B,C的字符串,其中A,B,C可以转换成’(‘或‘)’,并且相同字符只能转换成相同的括号,问全部转换后得到的括号匹配是否合法。
思路:首先第一个必须是’(’,最后一个必须是‘)’,否则不可能。求出对应的字符后,那么考虑剩下的字符转换成’(’,还是’)’,转换完后就是括号匹配问题了(可以用栈来求)。
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
//const double p1 = 3.141592653589793238462643383;
using namespace std;
void solve()
{
//getchar();
int n,flag = 0;
char s[55],t[55];
int cnt[55];
cin >> s;
n = strlen(s);
for(int i = 0; i <= 30; i++) t[i] = ' ';
if(s[0] == s[n-1]) {
puts("NO");
return;
}
int l = 0;
int k = s[0]-'A';
int k1= s[n-1]-'A';
t[k] = '(';
t[k1] = ')';
int xb = -1;
for(int i = 0; i < n; i++){
k = s[i]-'A';
if(t[k] == ' ') t[k] = '(',xb=k;
}
//判断括号是否合法
for(int i = 0; i < n; i++){
int k = s[i]-'A';
if(t[k] == '(')l++;
else l--;
if(l < 0) {
l = -100;
break;
}
}
if(l == 0) flag = 1;
if(xb != -1 && l != 0){
t[xb] = ')';
l = 0;
for(int i = 0; i < n; i++){
int k = s[i]-'A';
if(t[k] == '(')l++;
else l--;
if(l < 0) {
l = -100;
break;
}
}
}
if(l == 0) flag = 1;
if(flag) puts("YES");
else puts("NO");
}
int main()
{
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
B. Berland Crossword:暴力
https://codeforces.com/contest/1494/problem/B
大意:给出一个n*n的白格子方正,同时约定最上,右,下,左有多少个黑格子,问是否存在。
思路:看图可以发现如果四个角中的某个角放了格子,那么相邻的边就会同时增加一个黑格子,所有枚举每个角上的格子放不黑格子,总共(2^2)*4中情况。
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
//const double p1 = 3.141592653589793238462643383;
using namespace std;
int n;
bool check(int u,int r,int d,int l)
{
if(u < 0 || r < 0 || d < 0 || l < 0)
return false;
if(u > n-2 || r > n-2 || d > n-2 || l > n-2)
return false;
return true;
}
void solve()
{
int u,r,d,l;
int u1,r1,d1,l1;
u1 = r1 = d1 = l1 = 0;
cin >> n >> u >> r >> d >> l;
int flag = 0;
for(int i = 0; i <= 1; i++){
for(int j = 0; j <= 1; j++){
for(int k = 0; k <= 1; k++){
for(int L = 0; L <= 1; L++){
u1=u,r1=r,d1=d,l1=l;
if(i) u1--,l1--;
if(j) u1--,r1--;
if(k) r1--,d1--;
if(L) l1--,d1--;
//cout << u1 << " " << r1 << " " << d1 << " " << l1 <<"\n";
if(check(u1,r1,d1,l1)){
flag = 1;
}
}
}
}
}
if(flag) puts("YES");
else puts("NO");
}
int main()
{
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
C. 1D Sokoban:二分
https://codeforces.com/contest/1494/problem/C
大意:给定n个箱子的位置,m个特殊位置的位置,人的起点在0,问最多能把多少个箱子推到特殊位置上。
思路:
1)在零右边的箱子只能往右边推,在零左边的箱子只能往左边推。
2)所有将箱子和特殊位置分为大于零和小于零两部分来求解。
3)以右边为例,枚举每个特殊位置,将当前特殊位置前面的所有箱子推到一起,用二分找出有多少个箱子(因为从零开始,所以即在a中大于b[i]的有多少个),假设是xb个,然后当最右边的箱子到了当前特殊位置的时候停,看[i-xb+1,xb]有多少个特殊位置,同样可以二分求。因为可能特殊位置上本来就放了箱子,所有同时还要加上当前特殊位置之后有的特殊位置中有几个特殊位置放了箱子。
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
//const double p1 = 3.141592653589793238462643383;
using namespace std;
vector<int>a,b,aa,bb;
map<ll,ll>mp;
void solve()
{
mp.clear();
a.clear(),aa.clear(),b.clear(),bb.clear();
int n,m,x,n1,n2;
cin >> n >> m;
n1 = n2 = 0;
for(int i = 0; i < n; i++) {
cin >> x;
if(x > 0) a.push_back(x);
else aa.push_back(abs(x));
mp[x] = 1;
}
sort(aa.begin(),aa.end());
for(int i = 0; i < m; i++){
cin >> x;
if(x > 0) {
b.push_back(x);
if(mp[x]) n1++;
}
else {
bb.push_back(abs(x));
if(mp[x]) n2++;
}
}
sort(bb.begin(),bb.end());
int len1 = 0,q,ans1=0,ans2=0;
if(b.size() && a.size()){
int nn = b.size(),len;
for(int i = 0; i < nn; i++){
if(mp[b[i]]) n1--;
int xb = upper_bound(a.begin(),a.end(),b[i])-a.begin();
int pos = upper_bound(b.begin(),b.end(),b[i]-xb)-b.begin();
// cout << xb << " " << pos << endl;
ans1 = max(ans1,i+1-pos+n1);
}
//cout << ans1 << endl;
}
if(bb.size() && aa.size()){
int nn = bb.size(),len;
for(int i = 0; i < nn; i++){
if(mp[-bb[i]]) n2--;
int xb = upper_bound(aa.begin(),aa.end(),bb[i])-aa.begin();
int pos = upper_bound(bb.begin(),bb.end(),bb[i]-xb)-bb.begin();
ans2 = max(ans2,i+1-pos+n2);
}
//cout << ans2 << endl;
}
cout << ans1+ans2 <<endl;
}
int main()
{
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}