Codeforces Round 114 简训
导语
第二次队内CF训练
涉及的知识点
贪心,思维
题目
A Regular Bracket Sequences
题目大意:t个数,每次给出一个n,输出满足括号匹配的长度为2n的字符串(用()),需要输出n个
思路:我居然用暴搜写半天我是沙币
思路其实很简单,自己想复杂了,每次假设最左边有i个(即可,然后先将这个i个(匹配,之后无脑输出()
暴搜
#include <bits/stdc++.h>
using namespace std;
const int maxn=100;
int t,n,ans,cnt,vis[maxn];
stack<bool>S;
void DFS(int x) {
if(ans==n)return ;
if(x==2*n+1) {
if(S.empty()) {
for(int i=1; i<=2*n; i++)
printf("%c",vis[i]==1?'(':')');
putchar('\n');
ans++;
}
return ;
}
if(S.size()&&S.top()==0)
return ;
else if(S.size()&&S.top()==1) {
vis[x]=0;
S.pop();
DFS(x+1);
vis[x]=-1;
S.push(1);
S.push(1);
vis[x]=1;
DFS(x+1);
vis[x]=-1;
S.pop();
} else if(S.empty()) {
S.push(1);
vis[x]=1;
DFS(x+1);
vis[x]=-1;
S.pop();
}
}
int main() {
scanf("%d",&t);
while(t--) {
memset(vis,-1,sizeof(vis));
vis[1]=1;
scanf("%d",&n);
S.push(1);
DFS(2);
ans=cnt=0;
while(S.size())S.pop();
}
return 0;
}
简易方法
#include <bits/stdc++.h>
using namespace std;
int t,n;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
for(int j=1; j<=i; j++)
printf("(");
for(int j=1; j<=i; j++)
printf(")");
for(int j=i+1; j<=n; j++)
printf("()");
putchar('\n');
}
}
return 0;
}
B Combinatorics Homework
题目大意:略
思路:拿数量次小的两个字符间隔插入数量最大的字符之间获得匹配的最小数值,相同字符相邻摆放获得匹配的最大数值,判断获得匹配的最大数值,判断给定的m是否在范围内即可
代码
#include <bits/stdc++.h>
using namespace std;
int t,a[3],m;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d%d%d%d",&a[0],&a[1],&a[2],&m);
int l=0,r=0;
r=a[0]-1+a[1]-1+a[2]-1;
sort(a,a+3);
a[2]-=a[1]+a[0];
l=a[2]-1;
if(m>=l&&m<=r)printf("YES\n");
else printf("NO\n");
}
return 0;
}
C Slay the Dragon
题目大意:略
思路:将英雄值升序排序,二分获得刚好大于x的值,特判第一个位置和找不到该值,其余的一般情况,特判找到的值与找到值的前一位置,获得两个值选择后的结果并比较最小值
代码
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+5;
ll a[N];
void solve() {
int n, m;
scanf("%d",&n);
ll suma = 0;
for(int i = 1; i <= n; i++) {
scanf("%lld",a+i);
suma+=a[i];
}
sort(a+1,a+n+1);
scanf("%d",&m);
for(int i = 1; i <= m; i++) {
ll x,y;
scanf("%lld%lld",&x,&y);
int pos = upper_bound(a+1,a+1+n,x)-a;//找到一个刚好大于的值
ll m1,m2;
if(pos == 1)//特判第一个位置
printf("%lld\n",(y-suma+a[1]>0?y-suma+a[1]:0));
else if(pos <= n) {//一般位置
m1 = x-a[pos-1]+(y-suma+a[pos-1]>0?y-suma+a[pos-1]:0);//前一个值,a值必定小于等于x
m2 = (y-suma+a[pos]>0?y-suma+a[pos]:0);//当前值
printf("%lld\n",min(m1,m2));
} else
printf("%lld\n",x-a[n]+(y-suma+a[n]>0?y-suma+a[n]:0));
}
}
int main() {
int t = 1;
while(t--)
solve();
return 0;
}