A.给定一个字符串,问是否存在不重叠的两个串”AB”和”BA”,顺序任意.
先从左到右遍历一遍,然后找出最靠左的”AB”的位置和”BA”的位置
然后从右往左遍历一遍,找出最靠右的”BA”的位置和”AB”的位置
然后比较一下就行了
/*************************************************************************
> File Name: A.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年06月05日 星期五 18时58分41秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
string str;
int main() {
while (cin >> str) {
int len = str.length();
int pos11 = -1, pos12 = -1, pos21 = -1, pos22 = -1;
for (int i = 0; i < len - 1; ++i) {
if (pos11 == -1 && str[i] == 'A' && str[i + 1] == 'B') {
pos11 = i;
}
if (pos12 == -1 && str[i] == 'B' && str[i + 1] == 'A') {
pos12 = i;
}
}
for (int i = len - 1; i > 0; --i) {
if (pos21 == -1 && str[i] == 'A' && str[i - 1] == 'B') {
pos21 = i - 1;
}
if (pos22 == -1 && str[i] == 'B' && str[i - 1] == 'A') {
pos22 = i - 1;
}
}
bool flag = 0;
if (pos11 != -1 && pos21 != -1 && pos11 + 1 < pos21) {
flag = 1;
}
if (pos12 != -1 && pos22 != -1 && pos12 + 1 < pos22) {
flag = 1;
}
if (flag) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
B.给定n个问题,以及它们的难度,问合法的方案数
n<=15,所以直接枚举
2n
就行
/*************************************************************************
> File Name: B.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年06月05日 星期五 17时55分00秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
int C[20];
int main() {
int n, l, r, x;
while (cin >> n >> l >> r >> x) {
for (int i = 0; i < n; ++i) {
cin >> C[i];
}
int ans = 0;
for (int i = 0; i < (1 << n); ++i) {
int sum = 0;
int bits = 0;
int maxs = -1, mins = inf;
for (int j = 0; j < n; ++j) {
if (i & (1 << j)) {
++bits;
sum += C[j];
maxs = max(maxs, C[j]);
mins = min(mins, C[j]);
}
}
if (bits >= 2 && sum >= l && sum <= r && maxs - mins >= x) {
++ans;
}
}
cout << ans << endl;
}
return 0;
}
C.给定一个长度不超过100的正整数,然后可以删除一些位置上的数,问是否存在方案,使得最后形成的数对8取模为0,如果存在,输出一组解
我是用dp来做的,似乎麻烦了点
dp[i][j][k] 表示前i位,删除j位,模8为k的可行性
然后记录这个状态的前驱状态,最后把答案迭代出来就行了,注意前导0
/*************************************************************************
> File Name: C.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年06月05日 星期五 18时03分45秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
string str;
bool dp[110][110][10];
bool use[110];
struct node {
int rest, del;
}last[110][110][10];
int main() {
while (cin >> str) {
memset(dp, 0, sizeof(dp));
dp[0][0][0] = 1;
last[0][0][0].rest = last[0][0][0].del = -1;
int n = str.length();
for (int i = 0; i < n; ++i) {
for (int j = 0; j <= i; ++j) {
for (int k = 0; k < 8; ++k) {
if (dp[i][j][k]) {
dp[i + 1][j + 1][k] = 1;
dp[i + 1][j][(k * 10 + str[i] - '0') % 8] = 1;
last[i + 1][j + 1][k].rest = k;
last[i + 1][j + 1][k].del = j;
last[i + 1][j][(k * 10 + str[i] - '0') % 8].rest = k;
last[i + 1][j][(k * 10 + str[i] - '0') % 8].del = j;
}
}
}
}
bool flag = 0;
int del;
for (int i = 0; i < n; ++i) {
if (dp[n][i][0]) {
flag = 1;
del = i;
break;
}
}
if (!flag) {
cout << "NO" << endl;
continue;
}
cout << "YES" << endl;
for (int i = 0; i <= n; ++i) {
use[i] = 0;
}
int m = n, rest = 0;
while (m > 0) {
node &now = last[m][del][rest];
if (now.del == del) {
use[m] = 1;
}
--m;
rest = now.rest;
del = now.del;
}
string ans ="";
for (int i = 1; i <= n; ++i) {
if (use[i]) {
ans += str[i - 1];
}
}
int len = ans.length();
int s = 0;
while (s != len - 1 && ans[s] == '0') {
++s;
}
for (int i = s; i < len; ++i) {
cout << ans[i];
}
cout << endl;
}
return 0;
}
D.给定k,让你构造一张无向连通图,且图中所有顶点的度为k,图中至少存在一条割边;如果答案不存在,输出NO
显然如果k是偶数一定无解
当k是奇数,由于图中存在割边,割边2侧的图是对称的,
考虑一侧的图,我yy的方法是,令一侧的点个数为2*k-1
设割边两侧的点编号为1, 2*k
先从1出衍生出点(2, 3, …, k)
然后从2出衍生出点(k + 1, k + 2, …, 2 * k - 1)
然后对于编号为(2, 3, …, k)的点,向编号为(k + 1, k + 2, …, 2 * k - 1)的点都连一条边
这个过程之后,编号为(k + 1, k + 2, …, 2 * k - 1)的点的度数就是k-1了
而共有k - 1个这样的点,k-1是偶数
所以只要两两互连就行了
另外一侧的图只要在输出的时候给点的编号加上2*k - 1的偏移量就行了
/*************************************************************************
> File Name: D.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年06月05日 星期五 20时19分03秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
bool mat[440][440];
bool use[440][440];
int main() {
int k;
while (~scanf("%d", &k)) {
if (k % 2 == 0) {
printf("NO\n");
continue;
}
memset(mat, 0, sizeof(mat));
for (int i = 2; i <= k; ++i) {
mat[1][i] = 1;
mat[i][1] = 1;
}
for (int i = 2; i <= k; ++i) {
for (int j = k + 1; j <= 2 * k - 1; ++j) {
mat[i][j] = mat[j][i] = 1;
}
}
for (int i = k + 1; i <= 2 * k - 1; i += 2) {
mat[i][i + 1] = 1;
mat[i + 1][i] = 1;
}
int ans = 0;
for (int i = 1; i <= 2 * k - 1; ++i) {
for (int j = 1; j <= 2 * k - 1; ++j) {
ans += mat[i][j];
}
}
++ans;
printf("YES\n");
printf("%d %d\n", 4 * k - 2, ans);
memset(use, 0, sizeof(use));
for (int i = 1; i <= 2 * k - 1; ++i) {
for (int j = 1; j <= 2 * k - 1; ++j) {
if (mat[i][j] && !use[i][j]) {
printf("%d %d\n", i, j);
printf("%d %d\n", i + 2 * k - 1, j + 2 * k - 1);
use[i][j] = use[j][i] = 1;
}
}
}
printf("%d %d\n", 1, 2 * k);
}
}
E.定义运算 a−>b a,b非零即一,仅当a为1,b为0时,结果为0,其他结果为1,不加括号时,运算顺序是从左到右,给定n个数,问通过这个操作这n个数 的运算结果是否可以为0,如果可以,就输出一种方案,否则输出NO
显然,如果最后一个数是1,一定无解
如果倒数第二个数为1,那么可以直接运算
如果倒数第二个数为0,而它前面是0,那么这2个数先计算,就可以得到1,再之前的数就可以顺序运算
如果倒数第二个数为0,而它前面是1,那么这2个数必须先计算,否则最后结果就是1 0 0 ,无论如何计算结果一定是1
所以我们只要从后往前这样考虑就行了,注意判断一种情况,考虑完所有的数,还是没能得到1,那么应该是NO的,比如1 0 0 这样的序列
/*************************************************************************
> File Name: E.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年06月05日 星期五 21时12分05秒
************************************************************************/
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
static const int N = 100100;
int Arr[N];
int leftNum[N];
int rightNum[N];
int main() {
int n;
while (~scanf("%d", &n)) {
for (int i = 1; i <= n; ++i) {
scanf("%d", &Arr[i]);
}
if (Arr[n]) {
printf("NO\n");
continue;
}
if (n == 1) {
printf("%s\n", Arr[n] ? "NO" : "YES");
if (!Arr[n]) {
printf("0\n");
}
continue;
}
if (n == 2) {
if (Arr[1] && !Arr[2]) {
printf("YES\n");
printf("1->0\n");
}
else {
printf("NO\n");
}
continue;
}
memset(leftNum, 0, sizeof(leftNum));
memset(rightNum, 0, sizeof(rightNum));
int last = Arr[n - 1];
int pos = -1;
bool flag = 0;
for (int i = n - 2; i >= 1; --i) {
if (last) {
flag = 1;
break;
}
if (!Arr[i]) {
++leftNum[i];
if (pos == -1) {
pos = i + 1;
}
flag = 1;
++rightNum[pos];
break;
}
else if (Arr[i]) {
++leftNum[i];
if (pos == -1) {
pos = i + 1;
}
++rightNum[pos];
}
}
if (!flag) {
printf("NO\n");
continue;
}
else {
printf("YES\n");
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= leftNum[i]; ++j) {
printf("(");
}
printf("%d", Arr[i]);
for (int j = 1; j <= rightNum[i]; ++j) {
printf(")");
}
if (i < n) {
printf("->");
}
}
printf("\n");
}
return 0;
}