A. Regular Bracket Sequence
只有一对括号‘()’,剩下的全部都是问号,每个问号都有可能是‘(’或者是‘)’,问能不能使所有的括号匹配。
最开始没有看到只有一对括号的那个条件,还写复杂了。
#include
using namespace std;
string s;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>s;
int n=s.size();
if(n&1||s[0]==')'||s[n-1]=='(')
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}
B. Red and Blue
因为r数组和b数组中的元素在a数组中的相对位置并没有改变,所以另r数组的最大前缀和为X,b数组的最大前缀和为Y,那么答案便是max( X , Y , X + Y )。
#include
using namespace std;
int n,m;
int r[200],b[200];
int f1[200],f2[200];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&r[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
int maxr=-1e5,maxb=-1e5;
for(int i=1;i<=n;i++)
{
f1[i]=f1[i-1]+r[i];
maxr=max(maxr,f1[i]);
}
for(int i=1;i<=m;i++)
{
f2[i]=f2[i-1]+b[i];
maxb=max(maxb,f2[i]);
}
int res=0;
res=max(maxr,maxb);
res=max(res,maxr+maxb);
res=max(res,0);
printf("%d\n",res);
}
//system("pause");
return 0;
}
C. Building a Fence
第一个栅栏和最后一个栅栏的位置是肯定的。求出每个栅栏的起点区间,然后与前一个栅栏相比较有没有公共边即可。如果2~n-1个栅栏都满足,那么不要忘记和最后一个确定的栅栏相比较。
#include
using namespace std;
const int N=2e5+10;
int h[N];
int top[N],low[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
top[1]=h[1],low[1]=h[1];
top[n]=h[n],low[n]=h[n];
int flag=0;
for(int i=2;i<n;i++)
{
top[i]=h[i]+k-1;//最高的起点
low[i]=h[i]; //最低的起点
top[i]=min(top[i],top[i-1]+k-1);
low[i]=max(low[i],low[i-1]-k+1);
if(low[i]>=top[i-1]+k||top[i]<=low[i-1]-k)
{
flag=1;
break;
}
}
if(low[n]>=top[n-1]+k||top[n]<=low[n-1]-k) flag=1;
if(flag==1) printf("NO\n");
else printf("YES\n");
}
//system("pause");
return 0;
}
D. Ceil Divisions
我们发现一个比n小的数除以n向上取整之后都为1。但是这样最后会留下一个n无法处理。于是我们就想着n该怎么处理。我最开始想到的是不断除以2,但是看到数据范围和最大的操作数,这样想显然是不对的。看到这个操作数,那么感觉最可能的是开平方。然后我们观察(n^1/2,n) ,我们发现n除以两次前者即为1。而且2e5不断开平方为200000 448 22 5 3 2,显然操作的次数是满足题目要求的。
#include
using namespace std;
const int N=2e5+10;
int h[N];
int top[N],low[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
top[1]=h[1],low[1]=h[1];
top[n]=h[n],low[n]=h[n];
int flag=0;
for(int i=2;i<n;i++)
{
top[i]=h[i]+k-1;//最高的起点
low[i]=h[i]; //最低的起点
top[i]=min(top[i],top[i-1]+k-1);
low[i]=max(low[i],low[i-1]-k+1);
if(low[i]>=top[i-1]+k||top[i]<=low[i-1]-k)
{
flag=1;
break;
}
}
if(low[n]>=top[n-1]+k||top[n]<=low[n-1]-k) flag=1;
if(flag==1) printf("NO\n");
else printf("YES\n");
}
//system("pause");
return 0;
}