A - 首字母大写
思路:把握好每个单词的首字母,正常处理即可,同时注意带空格的字符串读入。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int main()
{
char a[100];
cin.getline(a, 100);
int len = strlen(a);
for (int i = 0; i < len; i ++ ) {
if (i == 0 && a[i] >= 'a' && a[i] <= 'z') {
a[i] -= 32;
} else {
if (a[i - 1] == ' ' && a[i] >= 'a' && a[i] <= 'z') {
a[i] -= 32;
}
}
}
cout << a << endl;
return 0;
}
B - 验证子串
思路:运用strstr函数直接解决
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int main()
{
char a[210], b[210];
cin >> a >> b;
if (strstr(a, b)) {
printf("%s is substring of %s", b, a);
} else if (strstr(b, a)) {
printf("%s is substring of %s", a, b);
} else {
printf("No substring");
}
return 0;
}
C - 大小写转换
思路:多组样例,注意读入,正常处理字符即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int main()
{
string a;
while (cin >> a) {
for (int i = 0; i < a.size(); i ++ ) {
if (a[i] >= 'a' && a[i] <= 'z') {
a[i] -= 32;
}
}
cout << a << endl;
}
return 0;
}
D - Text Reverse
思路:翻转单词,处理时能够将不同的单词分开即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1010;
char a[maxn];
vector<char> b;
int main()
{
int t;
cin >> t;
getchar();
while (t -- ) {
b.clear();
cin.getline(a, 1010);
int n = strlen(a);
for (int i = 0; i < n; i ++ ) {
if (a[i] != ' ') {
b.push_back(a[i]);
} else {
reverse(b.begin(), b.end());
for (auto x : b) {
cout << x;
}
cout << " ";
b.clear();
}
}
reverse(b.begin(), b.end());
for (auto x : b) {
cout << x;
}
cout << endl;
}
return 0;
}
E - 排序
思路:与上题处理方式类似,把数字分开后排序
#include <stdio.h>
#include <string.h>
int a[1010];
char b[1010];
int main()
{
while (scanf("%s", b) != -1) {
int n = strlen(b);
int now = 0;
int cont = 0;
for (int i = 0; i < n; i ++ ) {
if (b[i] != '5') {
now = now * 10 + b[i] - '0';
} else {
if (i == 0 || b[i - 1] == '5') {
continue;
}
a[cont ++] = now;
now = 0;
}
}
if (b[n - 1] != '5') a[cont ++] = now;
for (int i = 0; i < cont - 1; i ++ ) {
for (int t = i + 1; t < cont; t ++ ) {
if (a[i] > a[t]) {
int temp = a[i];
a[i] = a[t];
a[t] = temp;
}
}
}
for (int i = 0; i < cont - 1; i ++ ) {
printf("%d ", a[i]);
}
printf("%d\n", a[cont - 1]);
}
return 0;
}
F - What Are You Talking About
思路:用字典中的单词替换文章中的单词,这里采用了哈希表来存储这些单词,当然也可以采用不同的方法来存储,最后将这些单词替换即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3010;
unordered_map<string, string> mp;
char a[maxn];
int main()
{
string b;
cin >> b;
if (b == "START") {
while (1) {
string x, y;
cin >> x;
if (x == "END") break;
cin >> y;
mp[y] = x;
}
}
cin >> b;
getchar();
if (b == "START") {
while (1) {
cin.getline(a, 3010);
if (!strcmp(a, "END")) break;
int n = strlen(a);
string x = "";
for (int i = 0; i < n; i ++ ) {
if (a[i] >= 'a' && a[i] <= 'z') {
x += a[i];
} else {
if (mp.count(x)) {
cout << mp[x];
} else {
cout << x;
}
cout << a[i];
x = "";
}
}
cout << endl;
}
}
return 0;
}
G - AC Me
思路:统计字符,注意是多样例读入。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 10;
char a[maxn];
int cont[30];
int main()
{
while (cin.getline(a, 100010)) {
int len = strlen(a);
memset(cont, 0, sizeof cont);
for (int i = 0; i < len; i ++ ) {
cont[a[i] - 'a'] ++;
}
for (int i = 0; i <= 25; i ++ ) {
printf("%c:%d\n", i + 'a', cont[i]);
}
printf("\n");
}
return 0;
}
H - 剪花布条
思路:数据范围比较小,这里直接暴力处理就行,注意这个字符串之间不可以重叠
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int main()
{
string a, b;
while (1) {
int ans = 0;
cin >> a;
if (a == "#") break;
cin >> b;
for (int i = 0; i < a.size(); i ++ ) {
if (a[i] == b[0]) {
int now = i;
bool sign = true;
int t = 0;
while (t < b.size() && a[now] == b[t]) {
now ++;
t ++;
}
if (t == b.size()) {
ans ++;
i = now - 1;
}
}
}
cout << ans << endl;
}
return 0;
}
I - 子串查找
思路:kmp模板题,可以先了解一下kmp算法,再来做题
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
string a, b;
const int maxn = 1e6 + 10;
int ne[maxn];
void getnext() {
int i, j = -1;
ne[0] = -1;
for (i = 1; i < b.size(); i ++ ) {
while (j >= 0 && b[i] != b[j + 1]) j = ne[j];
if (b[j + 1] == b[i]) {
j ++;
}
ne[i] = j;
}
}
void kmp() {
if (b.size() == 0) return;
getnext();
int j = -1;
int ans = 0;
for (int i = 0; i < a.size(); i ++ ) {
while (j >= 0 && b[j + 1] != a[i]) j = ne[j];
if (b[j + 1] == a[i]) j ++;
if (j == b.size() - 1) {
ans ++;
j = ne[j];
}
}
cout << ans;
}
int main()
{
cin >> a >> b;
kmp();
return 0;
}
J - 字符串最大跨距
思路:输出两个字符之间的最大跨度,即找到最左边的第一个字符和最右边的第二个字符,输出两者之间的字符个数,当然会有不存在的特例存在,即第一个字符并不在第二个字符的左边,这时特判下结果即可
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 350;
char a[maxn], b[20], c[20], d[maxn];
int main()
{
int pos1 = 0x3f3f3f3f, pos2 = -0x3f3f3f3f;
scanf("%s", d);
int len = strlen(d);
int pos;
for (int i = 0; i < len; i ++ ) {
if (d[i] == ',') {
pos = i;
a[i] = '\0';
break;
}
a[i] = d[i];
}
int cont = 0;
for (int i = pos + 1; i < len; i ++ ) {
if (d[i] == ',') {
pos = i;
b[cont] = '\0';
cont = 0;
break;
}
b[cont ++] = d[i];
}
for (int i = pos + 1; i < len; i ++ ) {
c[cont ++] = d[i];
}
c[cont] = '\0';
int n1 = strlen(a), n2 = strlen(b), n3 = strlen(c);
for (int i = 0; i < n1; i ++ ) {
if (a[i] == b[0]) {
int now = i, t = 0;
while (t < n2 && now < n1 && a[now] == b[t]) {
now ++;
t ++;
}
if (t == n2) {
pos1 = min(pos1, i + t);
}
}
if (a[i] == c[0]) {
int now = i, t = 0;
while (t < n3 && now < n1 && a[now] == c[t]) {
now ++;
t ++;
}
if (t == n3) {
pos2 = max(pos2, i);
}
}
}
//cout << pos1 << endl << pos2 << endl;
if (pos1 == 0x3f3f3f3f || pos2 == -0x3f3f3f3f) {
cout << "-1" << endl;
} else {
if (pos2 - pos1 < 0) {
cout << "-1" << endl;
} else
cout << pos2 - pos1 << endl;
}
return 0;
}
K - Cyclic Nacklace
思路:这题是对kmp算法中在next数组的应用,在学完kmp算法后可以输出这几个字符串的next数组来寻找规律。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string a;
const int maxn = 1e5 + 10;
int ne[maxn];
void getnext() {
int j = -1;
ne[0] = -1;
for (int i = 1; i < a.size(); i ++ ) {
while (j >= 0 && a[j + 1] != a[i]) j = ne[j];
if (a[j + 1] == a[i]) j ++;
ne[i] = j;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t -- ) {
cin >> a;
memset(ne, 0, sizeof ne);
getnext();
// for (int i = 0; i < a.size(); i ++ ) {
// cout << ne[i] << " " ;
// }
// cout << endl;
int n = a.size();
if (ne[n - 1] == -1) {
cout << n << endl;
} else {
int pos = n - 1;
int cont = 0;
while (ne[pos] > 0) {
pos --;
cont ++;
}
if (ne[pos] == 0) {
cont ++;
}
int xh = n - cont;
int ans = cont % xh;
if (ans != 0) {
ans = xh - ans;
}
cout << ans << endl;
}
}
return 0;
}
L - 最长回文
思路:这题算是Manacher算法的模板题,可以先学习Manacher算法后再来做题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int len[maxn];
char a[maxn], na[maxn];
int main()
{
while (scanf("%s", a) != -1) {
int len1 = strlen(a);
int cont = 2;
na[0] = '*';
na[1] = '#';
for (int i = 0; i < len1; i ++ ) {
na[cont ++] = a[i];
na[cont ++] = '#';
}
na[cont ++] = '^';
na[cont] = '\0';
memset(len, 0, sizeof len);
int mx = -1, ans = -1, po = -1;
for (int i = 0; i < cont; i ++ ) {
if (mx > i) {
len[i] = min(len[2 * po - i], mx - i);
} else {
len[i] = 1;
}
while (na[i - len[i]] == na[i + len[i]]) {
len[i] ++;
}
if (mx < i + len[i]) {
mx = i + len[i];
po = i;
}
ans = max(ans, len[i]);
}
cout << ans - 1 << endl;
}
return 0;
}
使用string,用cin读入时要开优化,否则会超时
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
string a;
int len[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (cin >> a) {
string na = "";
na += "*#";
for (int i = 0; i < a.size(); i ++ ) {
na += a[i];
na += '#';
}
na += "^";
memset(len, 0, sizeof len);
int mx = -1, ans = -1, po = -1;
for (int i = 0; i < na.size(); i ++ ) {
if (mx > i) {
len[i] = min(len[2 * po - i], mx - i);
} else {
len[i] = 1;
}
while (na[i - len[i]] == na[i + len[i]]) {
len[i] ++;
}
if (mx < i + len[i]) {
mx = i + len[i];
po = i;
}
ans = max(ans, len[i]);
}
cout << ans - 1 << endl;
}
return 0;
}