ABC 452 A - D 题解

ABC 452 A - D 题解

A:Gothec

题意

以下几天被称为季节性节日:

  • 一月 \(7\) 日。
  • 三月 \(3\) 日。
  • 五月 \(5\) 日。
  • 七月 \(7\) 日。
  • 九月 \(9\) 日。

如果 \(M\)\(D\) 日是季节性节日,那么输出 Yes。否则输出 No

思路

这题简单枚举一下就行了。如果是这五个节日就输出。

代码部分

#include <bits/stdc++.h>
using namespace std;
int m, d;
int main()
{
	cin >> m >> d;
	if((m == 1 && d == 7) || (m == 3 && d == 3) || (m == 5 && d == 5) || (m == 7 && d == 7) || (m == 9 && d == 9))
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
    return 0;
}

B:Draw Frame

题意

这个题意其实就是输出一个 \(H\)\(W\) 列的网格,其靠边的单元格都是 #,而中间的单元格都是 .

思路

首先枚举每个单元格,设第 \(i\) 行第 \(j\) 个单元格为 \(c_{i, j}\),则有:

\[\left\{\begin{array}{l} \text{若 } i = 1, i = h, j = 1, j = w : c_{i, j} = '\#' \\ \text{否则} : c_{i, j} = '.' \end{array}\right. \]

代码部分

#include <bits/stdc++.h>
using namespace std;
int h, w;
int main()
{
	cin >> h >> w;
	for(int i = 1;i <= h;i ++)
	{
		for(int j = 1;j <= w;j ++)
		{
			if(i == 1 || i == h || j == 1 || j == w)
				cout << "#";
			else
				cout << ".";
		}
		cout << endl;	
	}

    return 0;
}

C:Fishbones

题意

这个题意乱七八糟的,刚看的时候都没理解在说啥。因此,我来简化一下题意。

\(M\) 个字符串,第 \(i\) 个为 \(S_i\)
我们有 \(N\)普通槽位,第 \(i\) 个槽位需要放进长度为 \(A_i\) 的字符串。
还有一个特殊槽位。我们在其中必须放一个长度为 \(N\) 的字符串,且放入的特殊槽位的字符串第 \(i\) 位需要等于第 \(j\) 个普通槽位中字符串的第 \(B_j\) 位。
表达来说就是要满足 \(S_i = S_{B_j}\)

特殊槽位可以放几个字符串

思路

其实这题就是个暴力的思路。因为题目中提到了“允许重复”,因此我们只需要记录长度为 \(x\) 的字符串,第 \(y\) 位是否为 \(z\)(记录为 \(mp[x][y][z] = 1\)),然后就可以通过枚举特殊槽位的字符串,然后判断可行性就行了。这个思路是因为看到 \(M\) 比较大,而 \(N\),以及每个字符串的长度很小想到的。
就比如枚举了特殊槽位的字符串(设字符串为 \(s\)),然后判断后面对于每个字符(设为第 \(i\) 位,且设当前是第 \(j\) 个普通槽位),如果 \(mp[A_j][b_j][c] = 1\),说明可行,否则就不行。

代码部分

#include <bits/stdc++.h>
using namespace std;
int n, m;
int a[20], b[20];
bool mp[20][20][40];
string s[200010];
//mp[i][j][k] : 存在长度为 i 的字符串,第 j 位字母为 k。 
int main()
{
	cin >> n;
	for(int i = 1;i <= n;i ++)
		cin >> a[i] >> b[i];
	
	cin >> m;
	for(int i = 1;i <= m;i ++)
	{
		cin >> s[i];
		for(int j = 0;j < s[i].length();j ++)
			mp[s[i].length()][j + 1][s[i][j] - 'a'] = 1;
	}
	for(int i = 1;i <= m;i ++)
	{
		bool fg = 0;
		if(s[i].length() == n)
			for(int j = 0;j < s[i].length();j ++)
			{
				if(!mp[a[j + 1]][b[j + 1]][s[i][j] - 'a'])
				{
					fg = 1;
					break;
				}
			}
		else
			fg = 1;
		if(fg)
			cout << "No" << endl;
		else
			cout << "Yes" << endl;
	}
    return 0;
}

D:No-Subsequence Substring

首先声明,我无法证明我的做法能在数据强度足够大的情况下通过此题(我的时间复杂度其实过不了,但是在此题中对了)。对于本题,我仅做自己的思路记录与介绍。

题意

给你两个个由小写字母组成的字符串 \(S\)\(T\),求 \(S\) 所有子串中,子序列不含 \(T\) 的数量。

思路

\(n\)\(S\) 的长度,\(m\)\(T\) 的长度。
我们从字符串 \(S\) 每一位开始枚举,一定能枚举出 \(S\) 的每个子串。
我们在枚举的过程中,不断找当前是否已经出现了 \(T\)(作为子序列)。如果出现了,就记录一下现在枚举到了第 \(j\) 位。若现在枚举到了字符串 \(S\) 的第 \(i\) 位,则从第 \(i\) 位出现,有 \(j - 1 - i\) 个子串是合法的。若没有出现,则有 \(n - i\) 个子串是合法的。

再次声明:这个算法时间复杂度约为 \(O(n ^ 2)\),能过此题是因为数据较弱吧,并不是正解,仅供记录一下!

代码部分

#include <bits/stdc++.h>
using namespace std;
string s, t;
int main()
{
    cin >> s >> t;
    int n = s.length(), m = t.length();
    long long ans = 0;
    for(int i = 0;i < n;i ++)
	{
        int j = i, x = 0, r;
        while(x < m && j < n)
		{
            if(s[j] == t[x])
                x ++;
            j ++;
        }
        if(x == m)
            r = j - 1;
        else
        	r = n;
        ans += r - i;
    }
    
    cout << ans << endl;
    return 0;
}

posted on 2026-04-08 21:54  Leo_29  阅读(14)  评论(0)    收藏  举报

导航