Codeforces Round #689 (Div. 2), based on Zed Code Competition 2020题解 A、B

题目链接https://codeforces.com/contest/1461

A. String Generation

题目

One fall day Joe got bored because he couldn’t find himself something interesting to do. Marty suggested Joe to generate a string of length n to entertain him somehow. It didn’t seem particularly difficult, but Joe’s generated string had to follow these rules:

the string may only contain characters ‘a’, ‘b’, or ‘c’;
the maximum length of a substring of this string that is a palindrome does not exceed k.

A string a is a substring of a string b if a can be obtained from b by deletion of several (possibly, zero or all) characters from the beginning and several (possibly, zero or all) characters from the end. For example, strings “a”, “bc”, “abc” are substrings of a string “abc”, while strings “ac”, “ba”, “cba” are not.
在这里插入图片描述

A string is a palindrome if it reads the same from the left to the right and from the right to the left. For example, strings “abccba”, “abbba”, “aba”, “abacaba”, “a”, and “bacab” are palindromes, while strings “abcbba”, “abb”, and “ab” are not.

Now Joe wants to find any correct string. Help him! It can be proven that the answer always exists under the given constraints.

Input
Each test contains one or more test cases. The first line contains the number of test cases t (1≤t≤10).

The only line of each test case contains two integers n and k (1≤k≤n≤1000) — the required string length and the maximum length of a palindrome substring, respectively.

Output
For each test case, print any string that satisfies the conditions from the problem statement. If there are multiple correct answers, you can print any one of them. It can be proven that the answer always exists under the given constraints.

题意

构建一个仅有‘a’,‘b’,'c’组成的长度为n的字符串,使得其最大的回文子串长度为k(从左往右读和从右往左读是同样的),tip:注意子串和子序列的区别,子串是连续的,子序列可以是不连续的

思路

我们可以设想最简单的方法让前k个全为a,这样就满足有k长度的回文子串了,关键是要保证这个是最大的。我很自然想到,后面全都用bcbc…这样会不会成立,但我发现bcb时产生了一个长度为3的回文子串,那么怎么样才能避免呢,两个字符不可避免的会产生回文子串,我想到可以把a加进来,aaaa…aabcabca…

代码

#include<bits/stdc++.h>
typedef long long ll;
 
using namespace std;
 
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        for(int i=0;i<k;++i)
        cout<<"a";
        for(int i=0;i<n-k;++i)
        {
            char c='a'+(1+i)%3;
            cout<<c;
        }
        cout<<endl;
    }
    getchar();
    getchar();
}

B. Find the Spruce

题目

Holidays are coming up really soon. Rick realized that it’s time to think about buying a traditional spruce tree. But Rick doesn’t want real trees to get hurt so he decided to find some in an n×m matrix consisting of “*” and “.”.

To find every spruce first let’s define what a spruce in the matrix is. A set of matrix cells is called a spruce of height k with origin at point (x,y) if:

All cells in the set contain an “*”.
For each 1≤i≤k all cells with the row number x+i−1 and columns in range [y−i+1,y+i−1] must be a part of the set. All other cells cannot belong to the set.
Examples of correct and incorrect spruce trees:
在这里插入图片描述

Now Rick wants to know how many spruces his n×m matrix contains. Help Rick solve this problem.

Input
Each test contains one or more test cases. The first line contains the number of test cases t (1≤t≤10).

The first line of each test case contains two integers n and m (1≤n,m≤500) — matrix size.

Next n lines of each test case contain m characters ci,j — matrix contents. It is guaranteed that ci,j is either a “.” or an “*”.

It is guaranteed that the sum of n⋅m over all test cases does not exceed 5002 (∑n⋅m≤5002).

Output
For each test case, print single integer — the total number of spruces in the matrix.

题意

给你一个n*m(1<=n,m<=500,∑n⋅m≤5002)大小由’.‘和’ * '组成的矩形,要求你求出总共有多少个“树”。关于树的定义说起来有点麻烦,可以看上面的图片和样例比较容易理解。

思路

这次比赛一大半时间都在做这道题,一方面是没有想到简单的方法,另一方面是看到很多人都做出来了。最后还是以一个比较复杂的方法过了
首先想到的肯定是遍历矩形,对于每一个’ * ',判断由他作为“树顶”的树的高度,把答案加上这个高度就行了。但是这样会超时,试想一个500 * 500的矩形中都是‘’ ,时间复杂度为O(n 2 m2),那么就会超时。
这里我采用了分段的方法,把每段连续‘ * ’表示为一个区间,那么依旧是遍历矩形,但是只需要遍历下一行中的每一段,如果存在一个段的边界大于我所需的边界就可。最坏的情况是。和 * 交替分布,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值