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}\),则有:
代码部分
#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;
}
浙公网安备 33010602011771号