A. Two Substrings
题意:问一个字符串中是否同时存在AB和BA,其中AB和BA不能共用同一个B或A。 题解:扫一遍即可。可以考虑如下策略:先找AB,然后从B后的位置继续找BA;再另按BA-AB的顺序找一遍即可。复杂度O ( n ) 。窝的代码则直接暴力出所有的AB和BA位置,只要出现不重叠的两个就O K ~数据不大,随便搞。 参考代码:
#include <bits/stdc++.h>
using namespace std ;
int main() {
string str;
while (cin >> str) {
vector <int > ab;
vector <int > ba;
for (int i = 0 ; i < str.length() - 1 ; ++i) {
if (str[i] == 'A' && str[i + 1 ] == 'B' ) {
ab.push_back(i);
} else if (str[i] == 'B' && str[i + 1 ] == 'A' ) {
ba.push_back(i);
}
}
bool flag = false ;
for (int i = 0 ; i < ab.size(); ++i) {
for (int j = 0 ; j < ba.size(); ++j) {
if (abs (ab[i] - ba[j]) > 1 ) {
flag = true ;
break ;
}
}
if (flag) {
break ;
}
}
cout << (flag ? "YES" : "NO" ) << endl;
}
return 0 ;
}
B. Preparing Olympiad
题意:n 个问题,每个问题有一个难度值,要选出来一些。问满足以下条件的方案数:
至少选2个
难度值的和在区间[ l , r ] 内 最难和最简单的问题间的难度值差要≥ x
题解:数据很小( n ≤ 15 ) ,因此我们可以O ( 2 n ) 地枚举子集即可。为了方便讨论,可以先排序一下,这样的话前缀和以及难度差都可以平均O ( 1 ) 地得到。 参考代码:
#include <bits/stdc++.h>
using namespace std ;
const int MAX = 16 ;
int sum[MAX];
int c[MAX];
int n, l, r, x;
bool check(int state) {
int sum = 0 , mind = 0xfffffff , maxd = -1 ;
for (int i = 0 ; i < n; ++i) {
if (state & 1 ) {
sum += c[i];
if (c[i] > maxd) {
maxd = c[i];
}
if (c[i] < mind) {
mind = c[i];
}
}
state >>= 1 ;
}
if (sum < l || sum > r || (maxd - mind) < x) {
return false ;
}
return true ;
}
int main() {
while (~scanf (" %d %d %d %d" , &n, &l, &r, &x)) {
for (int i = 0 ; i < n; ++i) {
scanf (" %d" , c + i);
}
sort(c, c + n);
memset (sum, 0 , sizeof (sum));
sum[0 ] = c[0 ];
for (int i = 1 ; i < n; ++i) {
sum[i] = sum[i - 1 ] + c[i];
}
int ans = 0 ;
for (int i = 0 ; i < (1 << n); ++i) {
if (check(i)) {
ans++;
}
}
printf ("%d\n" , ans);
}
return 0 ;
}
C. Divisibility by Eight
题意:给个不超过100位的数,删掉一些位上的数字,能否得到一个能被8整除的值。 题解:考虑阉割后的结果x 满足x % 8 = 0 ,由于1000 % 8 = 0 ,如果x 的位数大于3位:设y = x % 1000
z = x 1000
那么x = y + z ,由于z % 1000 = 0 ,必然有z % 8 = 0 ,于是只需要判断是否y % 8 = 0 即可。也就是说,我们只需要判断x 的后3位即可,也正因此,我们最多只需要找3位即可。数据不大可以直接枚举出来。对于少于2位的情况,当然也可以直接枚举。窝则枚举了1000以内的8的倍数,再依次暴力判断。 参考代码:
#include <bits/stdc++.h>
using namespace std ;
pair<bool , string > judge1(string x) {
for (int i = x.length() - 1 ; i >= 0 ; --i) {
if (x[i] == '0' ) {
return make_pair(true , "0" );
}
}
return make_pair(false , "joke" );
}
bool judge2(int x) {
if (x == 0 ) {
return false ;
}
while (x) {
if (x % 10 == 0 ) {
return false ;
}
x /= 10 ;
}
return true ;
}
string toString(int x) {
string res = "" ;
if (x == 0 ) {
res = "0" ;
}
while (x) {
res = (char )(x % 10 + '0' ) + res;
x /= 10 ;
}
return res;
}
void init(vector <string > & x) {
for (int i = 1 ; i < 1000 ; ++i) {
if (i % 8 == 0 && judge2(i)) {
x.push_back(toString(i));
}
}
}
pair<bool , string > judge3(string x, string sub) {
int i = 0 , j = 0 ;
while (i < x.size() && j < sub.size()) {
if (x[i] == sub[j]) {
++i;
++j;
} else {
++i;
}
}
if (j == sub.size()) {
return make_pair(true , sub);
} else {
return make_pair(false , "fuck" );
}
}
int main() {
vector <string > box;
init(box);
string num;
while (cin >> num) {
pair<bool , string > ans = judge1(num);
if (ans.first) {
cout << "YES\n0" << endl;
} else {
bool flag = false ;
for (int i = 0 ; i < box.size(); ++i) {
ans = judge3(num, box[i]);
if (ans.first) {
cout << "YES\n" << ans.second << endl;
flag = true ;
break ;
}
}
if (!flag) {
cout << "NO" << endl;
}
}
}
return 0 ;
}
D和E留着下次补…