题目链接: 点击打开链接
A: 给出n个字符串, 要求从中挑选数个字符串构成一个长串最长, 该长串又一个或两个字母组成.
模拟题, 遍历n个字符串, 每次遍历通过两个字符a, b判断该字符串是否由一个或两个字母组成, 若是则数组中加上此字符串长度. 最终求
最大长度时, 如果字母相同, 则此时长度为dp[i][j]一半.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1005;
char s[105][MAXN];
int n, dp[30][30], ans;
int main(int argc, char const *argv[])
{
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%s", s[i]);
for(int i = 0; i < n; ++i) {
char a = '$', b = '$';
int len = strlen(s[i]);
bool flag = false;
for(int j = 0; j < len; ++j) {
if(a == '$') a = s[i][j];
else if(b == '$' && s[i][j] != a) b = s[i][j];
else if(s[i][j] != a && s[i][j] != b) {
flag = true;
break;
}
}
if(flag) continue;
if(b == '$')
for(int j = 0; j < 26; ++j) {
dp[a - 'a'][j] += len;
dp[j][a - 'a'] += len;
}
else {
dp[a - 'a'][b - 'a'] += len;
dp[b - 'a'][a - 'a'] += len;
}
}
for(int i = 0; i < 26; ++i)
for(int j = 0; j < 26; ++j)
if(i == j) ans = max(ans, dp[i][j] / 2);
else ans = max(ans, dp[i][j]);
printf("%d\n", ans);
return 0;
}
B: 给出一个区间(x1, x2), n个k, b的值, 每个k, b可以确定一条直线, 问你在给定区间内会不会有相交的情况.
脑洞题, 求出每条直线在区间端点的值, 按照左端由低到高排序, 从右端开始遍历, 前一个比后一个大说明在此区间内一定有交点.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "utility"
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
int n;
bool flag;
ll x1, x2, k, b;
pair<ll, ll> p[MAXN];
int main(int argc, char const *argv[])
{
scanf("%d", &n);
scanf("%lld%lld", &x1, &x2);
for(int i = 0; i < n; ++i) {
scanf("%lld%lld", &k, &b);
p[i] = make_pair(k * x1 + b, k * x2 + b);
}
sort(p, p + n);
for(int i = 1; i < n; ++i)
if(p[i].second < p[i - 1].second) {
flag = true;
break;
}
if(flag) printf("YES\n");
else printf("NO\n");
return 0;
}