本场比赛打得心态炸了 ,TB比较好想,但是调了好久…
比赛链接
TA ABC String
题意:就是括号匹配 A B C分别代表‘ { ’ 或‘ } ’,问能不能让括号匹配。
idea:也可以不用栈,扫一遍就好
ACcode
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
int n,len,num1,num2,num3;
string s;
int main()
{
cin>>n;
num1 = 0;
num2 = 0;
num3 = 0;
while( n-- )
{
int sum = 0;
bool pd = true;
map<char,int> ma;
cin>>s;
len = s.size();
ma[ s[0] ] = 1;
ma[ s[len-1] ] = -1;
if( s[0]==s[len-1] ) pd = false;
else
{
for(int i=0;i<len;i++)
{
if( ma[ s[i] ]==1 ) num1++;
else if( ma[ s[i] ]==-1 ) num2++;
else num3++;
}
if( num1==num2 && num3!=0 ) pd = false;
else if( num1<num2 && num1+num3!=num2 ) pd = false;
else if( num1>num2 && num1!=num2+num3 ) pd = false;
else
{
num3 = 0;
if( num1<num2 ) num3 = -1;
else if( num2>num1 ) num3 = 1;
for(int i=0;i<len;i++)
{
if( ma[ s[i] ] != 0 ) sum += ma[ s[i] ];
else sum += num3;
if( sum<0 )
{
pd = false;
break;
}
}
}
}
if( pd ) printf("YES\n");
else printf("NO\n");
}
return 0;
}
TB Berland Crossword
题意:给定u,r,d,l四个量,表示在一个n∗n的网格中上边有u个涂黑,右边有r个涂黑,下边有d个涂黑,左边有l个涂黑,问是否能满足要求。
idea:枚举四个角各个情况一共16种情况,判断有没有满足情况的情况
ACcode
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define MIN 0xc0c0c0c0
#define N 101
using namespace std;
int t,n,a[10],u,d,l,r,tu,tl,tr,td;
bool check(int i)
{
if( i>=0 && i<=n-2 ) return true;
else return false;
}
int main()
{
cin>>t;
while( t-- )
{
bool pd = false;
scanf("%d %d %d %d %d",&n,&u,&r,&d,&l);
for(int i=0;i<=1;i++)
{
for(int j=0;j<=1;j++)
{
for(int k=0;k<=1;k++)
{
for(int p=0;p<=1;p++)
{
tu = u-i-j;
tr = r-j-k;
td = d-k-p;
tl = l-p-i;
if( check(tu) && check(td) && check(tl) && check(tr) )
{
pd = true;
}
}
}
}
}
if( pd ) printf("YES\n");
else printf("NO\n");
}
return 0;
}
TC 1D Sokoban
题意:最初一个人站在0点,有n个箱子分布在左右两侧,只能往左边或往右边推箱子,并且不能跨过一个箱子去推当前箱子后边的箱子,如果正在推的当前箱子后边还有一个箱子,那么推的时候后边的箱子会跟着动,然后还有m个特殊位置,求经过一定的推箱子操作后使得有多少个箱子在特殊位置上,求这个最大值。
iead:配合upper_bound和lower_bound函数枚举每一个特殊位置,假设离其最近且在其前面的一个箱子的位置为 a[j],人从 0 位置开始,知道将 a[j] 箱子推到 b[i],假设一共推了 x 个箱子,那么在区间 [b[i]-x+1,b[i]] 中寻找一共有多少个特殊位置,并且正负数要分开做。
ACcode
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define LL long long
#define N 201000
using namespace std;
int work(int a[],int b[],int lena,int lenb)
{
int last,pos,sum = 0,h = 0;
map<int,int> ma;
for(int i=1;i<=lena;i++)
{
ma[ a[i] ] = 1;
}
for(int i=1;i<=lenb;i++)
{
if( ma[ b[i] ] == 1 ) h++;
}
sum = h;
for(int i=1;i<=lenb;i++)
{
if( ma[ b[i] ] == 1 )
{
h--;
continue;
}
last = upper_bound(a+1,a+lena+1,b[i]) - a - 1;
pos = lower_bound(b+1,b+lenb+1,b[i]-last+1) - b;
sum = max( sum , h+i-pos+1 );
}
return sum;
}
int a1[N],a2[N],b1[N],b2[N],t,n,m,cnt11,cnt12,cnt21,cnt22,in,ans;
int main()
{
// freopen("in.txt","r",stdin);
cin>>t;
while( t-- )
{
cnt11 = cnt12 = cnt21 = cnt22 = 0;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&in);
if( in>0 ) a1[++cnt11] = in;
else a2[++cnt12] = -1*in;
}
for(int i=1;i<=m;i++)
{
scanf("%d",&in);
if( in>0 ) b1[++cnt21] = in;
else b2[++cnt22] = -1*in;
}
sort(a2+1,a2+cnt12+1);
sort(b2+1,b2+cnt22+1);
ans = 0;
ans += work( a1,b1,cnt11,cnt21);
ans += work( a2,b2,cnt12,cnt22 );
printf("%d\n",ans);
}
return 0;
}