A
题意:给你n个数,每个数可以使用任意次。问最小的无法得到的正整数,若不存在输出-1。
有1即可。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <map>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
int main()
{
int n;
while(scanf("%d", &n) != EOF) {
bool flag = false;
for(int i = 1; i <= n; i++) {
int v; scanf("%d", &v);
if(v == 1) {
flag = true;
}
}
printf(flag ? "-1\n" : "1\n");
}
return 0;
}
B
题意:给定一个大矩形和两个小矩形,问大矩形能否完全包含这两个小矩形,要求这两个小矩形不可以重复覆盖。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <map>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
int main()
{
int a1, b1, a2, b2, a3, b3;
while(scanf("%d%d", &a1, &b1) != EOF) {
scanf("%d%d", &a2, &b2);
scanf("%d%d", &a3, &b3);
bool flag = false;
if(a1 < b1) {
swap(a1, b1);
}
if(a2 < b2) {
swap(a2, b2);
}
if(a3 < b3) {
swap(a3, b3);
}
if(a2 + b3 <= a1 && max(b2, a3) <= b1) {
flag = true;
}
if(a2 + a3 <= a1 && max(b2, b3) <= b1) {
flag = true;
}
if(b2 + a3 <= a1 && max(a2, b3) <= b1) {
flag = true;
}
if(b2 + b3 <= a1 && max(a2, a3) <= b1) {
flag = true;
}
if(a2 + b3 <= b1 && max(b2, a3) <= a1) {
flag = true;
}
if(a2 + a3 <= b1 && max(b2, b3) <= a1) {
flag = true;
}
if(b2 + a3 <= b1 && max(a2, b3) <= a1) {
flag = true;
}
if(b2 + b3 <= b1 && max(a2, a3) <= a1) {
flag = true;
}
printf(flag ? "YES\n" : "NO\n");
}
return 0;
}
C
题意:给定六边形的顺时针边长,已知每个角度均为120度。问你边长为1的正三角形有多少个。
我们每隔一个角添上一个新角,然后补成一个大的正三角形,最后去掉添上的三个角即可。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <map>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
int a[7];
int S(int n) {
return n * n;
}
int main()
{
while(scanf("%d", &a[1]) != EOF) {
for(int i = 2; i <= 6; i++) {
scanf("%d", &a[i]);
}
printf("%d\n", S(a[1] + a[2] + a[3]) - S(a[1]) - S(a[3]) - S(a[5]));
}
return 0;
}
D
题意:两个字符串匹配判定条件有两个,满足一个即可。
1、两个字符串相等;
2、严格从中间均分两份A1 A2 和 B1 B2,满足A1匹配B1且A2匹配B2 或者 A1匹配B2且A2匹配B1。
直接递归两个串显然不行,发现只要两个串按照上述方法组合后的最小字典序新串相同,那么它们一定是匹配。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <map>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 1e5 + 10;
const int MOD = 1e9 + 7;
string Work(string a) {
int la = a.size(); if(la & 1) return a;
string a1 = a.substr(0, la >> 1), a2 = a.substr(la >> 1, la >> 1);
string b1 = Work(a1), b2 = Work(a2);
return b1 > b2 ? b2 + b1 : b1 + b2;
}
int main()
{
string a, b;
while(cin >> a >> b) {
a = Work(a); b = Work(b);
if(a == b) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
题意:每次只可以向下或者向右走,问你从(1, 1)到(n, n)的方案数,其中有m个格子是坏的。
dp[i] 表示到达第i个坏格子且不经过前面所有坏格子的方案数。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <map>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 1e5 + 10;
const int MOD = 1e9 + 7;
void add(LL &x, LL y) { x += y; if(x < 0) x += MOD; x %= MOD; }
pii a[2010];
LL fac[2 * MAXN];
LL pow_mod(LL a, int n) {
LL ans = 1;
while(n) {
if(n & 1) {
ans = ans * a % MOD;
}
a = a * a % MOD;
n >>= 1;
}
return ans;
}
LL C(int n, int m) {
return fac[n] * pow_mod(fac[m], MOD - 2) % MOD * pow_mod(fac[n-m], MOD - 2) % MOD;
}
LL Solve(int x1, int y1, int x2, int y2) {
int x = x2 - x1 + 1; int y = y2 - y1 + 1;
return C(x + y - 2, x - 1);
}
LL dp[2010];
int main()
{
fac[0] = 1LL;
for(int i = 1; i <= 200000; i++) {
fac[i] = fac[i-1] * i % MOD;
}
int n, m, k;
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
for(int i = 0; i < k; i++) {
scanf("%d%d", &a[i].first, &a[i].second);
}
sort(a, a + k); a[k] = pii(n, m);
for(int i = 0; i <= k; i++) {
dp[i] = 0; LL sum = 0;
for(int j = 0; j < i; j++) {
if(a[j].first <= a[i].first && a[j].second <= a[i].second) {
add(sum, dp[j] * Solve(a[j].first, a[j].second, a[i].first, a[i].second));
}
}
add(dp[i], Solve(1, 1, a[i].first, a[i].second) - sum);
}
printf("%lld\n", dp[k]);
}
return 0;
}