Codeforces Round #659 (Div. 2)题解总结

这次比赛又双叒叕爆零了…,A题看了一会儿没啥思路,又看了看其他的,结果还是不会。然后就倒头睡着了…是真滴困啊。

链接:https://codeforces.com/contest/1384

A. Common Prefixes

The length of the longest common prefix of two strings s=s1s2…sn and t=t1t2…tm is defined as the maximum integer k (0≤k≤min(n,m)) such that s1s2…sk equals t1t2…tk.

Koa the Koala initially has n+1 strings s1,s2,…,sn+1.

For each i (1≤i≤n) she calculated ai — the length of the longest common prefix of si and si+1.

Several days later Koa found these numbers, but she couldn’t remember the strings.

So Koa would like to find some strings s1,s2,…,sn+1 which would have generated numbers a1,a2,…,an. Can you help her?

If there are many answers print any. We can show that answer always exists for the given constraints.

Input
Each test contains multiple test cases. The first line contains t (1≤t≤100) — the number of test cases. Description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤100) — the number of elements in the list a.

The second line of each test case contains n integers a1,a2,…,an (0≤ai≤50) — the elements of a.

It is guaranteed that the sum of n over all test cases does not exceed 100.

Output
For each test case:

Output n+1 lines. In the i-th line print string si (1≤|si|≤200), consisting of lowercase Latin letters. Length of the longest common prefix of strings si and si+1 has to be equal to ai.

If there are many answers print any. We can show that answer always exists for the given constraints.

Example
inputCopy
4
4
1 2 4 2
2
5 3
3
1 3 1
3
0 0 0
outputCopy
aeren
ari
arousal
around
ari
monogon
monogamy
monthly
kevinvu
kuroni
kurioni
korone
anton
loves
adhoc
problems
Note
In the 1-st test case one of the possible answers is s=[aeren,ari,arousal,around,ari].

Lengths of longest common prefixes are:

Between aeren and ari →1
Between ari and arousal →2
Between arousal and around →4
Between around and ari →2

题意:
构造 n +1 个字符串,使得第 i 和 i+1 个字符串的公共前缀长度为 a[i]

思路:
看完理解人傻了…,第一个串全部构造成’a’,然后前缀相等的部分我们不用管,只需要改变上一个字符串的第一个非前缀字符就行了,后面也是不用管,然后直接输出。

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<set>
using namespace std;
typedef long long ll;
int inf = 0x3f3f3f3f;
const int N = 2e5 + 7;
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		string s = string(200, 'a');
		cout << s << endl;
		for (int i = 1; i <= n; i++) 
		{
			int x;
			cin >> x;
			s[x] = s[x] == 'a' ? 'b' : 'a';
			cout << s << endl;
		}
	return 0;
}

B1. Koa and the Beach (Easy Version)

The only difference between easy and hard versions is on constraints. In this version constraints are lower. You can make hacks only if all versions of the problem are solved.

Koa the Koala is at the beach!

The beach consists (from left to right) of a shore, n+1 meters of sea and an island at n+1 meters from the shore.

She measured the depth of the sea at 1,2,…,n meters from the shore and saved them in array d. di denotes the depth of the sea at i meters from the shore for 1≤i≤n.

Like any beach this one has tide, the intensity of the tide is measured by parameter k and affects all depths from the beginning at time t=0 in the following way:

For a total of k seconds, each second, tide increases all depths by 1.
Then, for a total of k seconds, each second, tide decreases all depths by 1.
This process repeats again and again (ie. depths increase for k seconds then decrease for k seconds and so on …).
Formally, let’s define 0-indexed array p=[0,1,2,…,k−2,k−1,k,k−1,k−2,…,2,1] of length 2k. At time t (0≤t) depth at i meters from the shore equals di+p[tmod2k] (tmod2k denotes the remainder of the division of t by 2k). Note that the changes occur instantaneously after each second, see the notes for better understanding.

At time t=0 Koa is standing at the shore and wants to get to the island. Suppose that at some time t (0≤t) she is at x (0≤x≤n) meters from the shore:

In one second Koa can swim 1 meter further from the shore (x changes to x+1) or not swim at all (x stays the same), in both cases t changes to t+1.
As Koa is a bad swimmer, the depth of the sea at the point where she is can’t exceed l at integer points of time (or she will drown). More formally, if Koa is at x (1≤x≤n) meters from the shore at the moment t (for some integer t≥0), the depth of the sea at this point — dx+p[tmod2k] — can’t exceed l. In other words, dx+p[tmod2k]≤l must hold always.
Once Koa reaches the island at n+1 meters from the shore, she stops and can rest.
Note that while Koa swims tide doesn’t have effect on her (ie. she can’t drown while swimming). Note that Koa can choose to stay on the shore for as long as she needs and neither the shore or the island are affected by the tide (they are solid ground and she won’t drown there).

Koa wants to know whether she can go from the shore to the island. Help her!

Input
The first line of the input contains one integer t (1≤t≤100) — the number of test cases. Description of the test cases follows.

The first line of each test case contains three integers n, k and l (1≤n≤100;1≤k≤100;1≤l≤100) — the number of meters of sea Koa measured and parameters k and l.

The second line of each test case contains n integers d1,d2,…,dn (0≤di≤100) — the depths of each meter of sea Koa measured.

It is guaranteed that the sum of n over all test cases does not exceed 100.

Output
For each test case:

Print Yes if Koa can get from the shore to the island, and No otherwise.

You may print each letter in any case (upper or lower).

Example
inputCopy
7
2 1 1
1 0
5 2 3
1 2 3 2 2
4 3 4
0 2 4 3
2 3 5
3 0
7 2 3
3 0 2 1 3 0 1
7 1 4
4 4 3 0 2 4 2
5 2 3
1 2 3 2 2
outputCopy
Yes
No
Yes
Yes
Yes
No
No
Note
In the following s denotes the shore, i denotes the island, x denotes distance from Koa to the shore, the underline denotes the position of Koa, and values in the array below denote current depths, affected by tide, at 1,2,…,n meters from the shore.

In test case 1 we have n=2,k=1,l=1,p=[0,1].

Koa wants to go from shore (at x=0) to the island (at x=3). Let’s describe a possible solution:

Initially at t=0 the beach looks like this: [s–,1,0,i].
At t=0 if Koa would decide to swim to x=1, beach would look like: [s,2–,1,i] at t=1, since 2>1 she would drown. So Koa waits 1 second instead and beach looks like [s–,2,1,i] at t=1.
At t=1 Koa swims to x=1, beach looks like [s,1–,0,i] at t=2. Koa doesn’t drown because 1≤1.
At t=2 Koa swims to x=2, beach looks like [s,2,1–,i] at t=3. Koa doesn’t drown because 1≤1.
At t=3 Koa swims to x=3, beach looks like [s,1,0,i–] at t=4.
At t=4 Koa is at x=3 and she made it!
We can show that in test case 2 Koa can’t get to the island.

题意:
有 n 片海域,每片海域有一个初始深度,每 2 * k秒,前 k秒 每秒深度 +1 ,后 k 秒每秒深度 -1 .有一个人想从海岸一边游到另一边 ,每秒它可以移动到下一片海域或者停留在当前海域,如果当前海域深度大于 l 他会被淹死,问他可不可以游到对岸。

思路:
用dp 的思路,dp[ i ][ j ] 表示第 j 秒 在第 i 片海域,如果此时海域高度小于 l 可以得到转移方程

dp[i][j]=max(dp[i][j-1],dp[i-1][j-1]);

j 的上限可以为 2k,要加入时间的取模,直接开到n * 2k

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<set>
using namespace std;
typedef long long ll;
int inf = 0x3f3f3f3f;
const int N = 2e5 + 7;
int n, k, l, h;
int dp[107][N], a[N];
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
        memset(dp, -1, sizeof(dp));
        scanf("%d%d%d", &n, &k, &l);
        for (int i = 1; i <= n; i++) 
            scanf("%d", &a[i]);
        for (int i = 0; i <= 2 * k * n; i++) 
            dp[0][i] = 0;
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= 2 * k * n; j++) 
            {
                if (dp[i - 1][j - 1] == -1 && dp[i][j - 1] == -1) continue;
                if (j % (2 * k) < k) h = a[i] + j % k;
                else h = a[i] + k - (j % k);
                if (h <= l) dp[i][j] = 0;
            }
        }
        int fl = 0;
        for (int i = 0; i <= 10000; i++) 
        {
            if (dp[n][i] == 0) fl = 1;
        }
        if (fl == 1) printf("YES\n");
        else printf("NO\n");
	}
	return 0;
}

C. String Transformation 1

Note that the only difference between String Transformation 1 and String Transformation 2 is in the move Koa does. In this version the letter y Koa selects must be strictly greater alphabetically than x (read statement for better understanding). You can make hacks in these problems independently.

Koa the Koala has two strings A and B of the same length n (|A|=|B|=n) consisting of the first 20 lowercase English alphabet letters (ie. from a to t).

In one move Koa:

selects some subset of positions p1,p2,…,pk (k≥1;1≤pi≤n;pi≠pj if i≠j) of A such that Ap1=Ap2=…=Apk=x (ie. all letters on this positions are equal to some letter x).
selects a letter y (from the first 20 lowercase letters in English alphabet) such that y>x (ie. letter y is strictly greater alphabetically than x).
sets each letter in positions p1,p2,…,pk to letter y. More formally: for each i (1≤i≤k) Koa sets Api=y.
Note that you can only modify letters in string A.

Koa wants to know the smallest number of moves she has to do to make strings equal to each other (A=B) or to determine that there is no way to make them equal. Help her!

Input
Each test contains multiple test cases. The first line contains t (1≤t≤10) — the number of test cases. Description of the test cases follows.

The first line of each test case contains one integer n (1≤n≤105) — the length of strings A and B.

The second line of each test case contains string A (|A|=n).

The third line of each test case contains string B (|B|=n).

Both strings consists of the first 20 lowercase English alphabet letters (ie. from a to t).

It is guaranteed that the sum of n over all test cases does not exceed 105.

Output
For each test case:

Print on a single line the smallest number of moves she has to do to make strings equal to each other (A=B) or −1 if there is no way to make them equal.

Example
inputCopy
5
3
aab
bcc
4
cabc
abcb
3
abc
tsr
4
aabd
cccd
5
abcbd
bcdda
outputCopy
2
-1
3
2
-1
Note
In the 1-st test case Koa:
selects positions 1 and 2 and sets A1=A2= b (aab→bbb).
selects positions 2 and 3 and sets A2=A3= c (bbb→bcc).
In the 2-nd test case Koa has no way to make string A equal B.
In the 3-rd test case Koa:
selects position 1 and sets A1= t (abc→tbc).
selects position 2 and sets A2= s (tbc→tsc).
selects position 3 and sets A3= r (tsc→tsr).

题意:
给定两个字符串s1 s2,你可以选 s1 中任意个相同字符都变成另一个大于变化前字符的字符,问最少操作数

思路:
尽可能将相同字符变到相同的目标字符打标记,求这样有多少组.
但考虑 aabb 到 bccc 只需要将2个a都变成b,再将后3个b变成c这样只需两步.
按照我们上面的思路是有a->b、a->c、b->c三次操作.
很明显能观察到这里是路径重复要去掉重复路径
并且我们这里只能从小字符到大字符变化,就可以用并查集合并路径
对 (每个连通块里的元素个数-1) 求和即可

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<set>
using namespace std;
typedef long long ll;
int inf = 0x3f3f3f3f;
const int N = 2e5 + 7;
int n, k, l, h;
int a[N];
string s1, s2;
int fa[N], sum[N];
int find(int x) {
    if (fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}
void conbine(int x, int y) 
{
    int temp1 = find(x);
    int temp2 = find(y);
    if (temp1 != temp2) sum[temp1] += sum[temp2];
    fa[temp2] = temp1;

}
void init() {
    for (int i = 1; i <= 30; i++) {
        fa[i] = i;
        sum[i] = 1;
    }
}
int main() 
{
    int t;
    cin >> t;
    while (t--) {
        int fl = 1, ans = 0;
        init();
        scanf("%d", &n);
        cin >> s1 >> s2;
        for (int i = 0; i < n; i++) {
            int x = s1[i] - 'a' + 1;
            int y = s2[i] - 'a' + 1;
            if (find(x) != find(y)) conbine(x, y);
            if (x > y) {
                fl = 0;
                break;
            }
        }
        if (fl == 0) {
            printf("-1\n");
            continue;
        }
        for (int i = 1; i <= 20; i++) find(i);
        for (int i = 1; i <= 20; i++) {
            if (i == find(i)) {
                ans += sum[find(i)] - 1;
                sum[find(i)] = 0;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值