【A】水题,模拟即可。
【B】水题,模拟即可。
【C】
【题意】
有n个鬼魂拜访她
每个蜡烛可以产生t秒的光
每秒可以点一支蜡烛,燃烧t秒
每个鬼魂拜访时至少有m个蜡烛
时间轴在[1,300]
【解题方法】 如果t<m,肯定-1
o11
o11
第一个鬼魂出现的时间设为a[0]
a[0]-1,a[0]-2,a[0]-m都必须点蜡烛
然后呢,第二个鬼魂呢?看它这个点延续过来多少个蜡烛,如果少,就相应在提前位置点蜡烛
【复杂度分析】O(n^3) 【代码】
int a[333],b[333];
int main()
{
int n,m,t;
cin>>n>>t>>m;
for(int i = 1; i <= n; i++){
int x;
cin>>x;
a[x] = 1;
}
if(t < m){
printf("-1\n");
return 0;
}
int ans = 0;
for(int i = 1; i <= 300; i++){
if(a[i]){
if(b[i]<m){
int need = m - b[i];
ans += need;
for(int st = i - 1; st >= i - need; st--){
for(int j = st + 1; j <= st + t; j++){
if(j > 0) b[j]++;
}
}
}
}
}
cout<<ans<<endl;
}
【D】给了n个3个字符的字符串,这些字符串是一个字符串的字串,问能不能找到一个长度为n+2的字符串使得满足这个条件? 【解题方法】白书上例题,把前两个字符和后两个字符hash成两个整数u,v,然后u,v之间连接一条有向边。然后判断这个有相同是否有欧拉通路,有的话,画出来就可以了。
【代码】
【复杂度分析】O(n*logn)
【E】给了n个条件,代表有n对(),每个l,r代表第i对括号左右下标相差的范围,问是否存在满足这个限制的括号序列?
【解题方法】贪心,可以用经典的栈来解决这个问题。步骤如下:
1.当前字符串长+1大于等于当前栈内元素个数+当前区间左端点值,相等时就是遇到一组匹配的"()"
2.若1且当前字符串长+1小于等于当前栈内元素个数+当前区间右端点值,
3.若2则栈顶“(”出栈,若不满足2则直接输出IMPOSSIBLE退出,因为此时找不到与之匹配的")",相当于无解
条件2很好理解因为给了一个区间,设"("的下标为l,与之匹配的")"下标为r,则有l = stack.size(),r∈[l+l0,l+r0]
最后若栈内还有元素则表示存在找不到匹配的"(",则输出IMPOSSIBLE
【代码】const int maxn = 2222;
int stk[maxn], top;
int pos[maxn], l[maxn], r[maxn];
char ans[maxn];
int len = 0;
int main()
{
int n;
cin>>n;
bool ok = 1;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &l[i], &r[i]);
if(ok == 0) continue;
stk[++top] = i;
pos[i] = len;
ans[len++] = '(';
while(top && pos[stk[top]] + l[stk[top]] <= len)
{
if(pos[stk[top]] + r[stk[top]] < len)
{
ok = 0;
break;
}
else{
ans[len++] = ')';
top--;
}
}
}
if(ok && !top)
{
printf("%s\n", ans);
}
else{
printf("IMPOSSIBLE\n");
}
}