最終試験の準備をしていたので、半月以上cfを逃してプレイしませんでした。今、私は補いに戻って、それがどのように感じられるかを調べます。
A.通常のブラケットシーケンス
質問ポータル:
アイデア:
括弧「()」のペアのみがあり、残りはすべて疑問符です。各疑問符は「(」または「)」の場合があります。すべての括弧に一致するかどうかを確認してください。
最初は、かっこだけでは状態が見えず、複雑でした。
ACコード
#include <bits/stdc++.h>
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.赤と青
質問ポータル:
アイデア:
r配列の要素とa配列のb配列の相対位置は変更されていないため、r配列の最大プレフィックス合計はXであり、b配列の最大プレフィックス合計はYです。答えはmax(X、Y、 X + Y)。
ACコード
#include<bits/stdc++.h>
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.フェンスを作る
質問ポータル:
アイデア:
最初のフェンスと最後のフェンスの位置は確実です。各フェンスの開始間隔を見つけ、共通のエッジがあるかどうか前のフェンスと比較します。2〜n-1のフェンスが満たされている場合は、最後に決定されたフェンスと比較することを忘れないでください。
ACコード
#include<bits/stdc++.h>
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を2で割ったものが前者であることがわかります。さらに、連続2e5の2乗は200,000 448 22 5 3 2です。明らかに、操作の数は問題の要件を満たしています。
ACコード
#include<bits/stdc++.h>
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;
}