Codeforces Round #313 (Div. 2)
大半年没有打Codeforces , 昨天开始恢复打Codeforces, 简直是, 欲语泪先流啊。
手残到爆的写错了范围, 手残的数漏了条件, 简直不能直视, 最坑爹的是, E题没时间写代码了。
Problem_A:
题意:
给n个数, 每个数可以用无限次, 求用这些数的和表示不出来的最小的正整数, 没有则输出 -1.
思路:
如果这n个数里面有1, 那么一定可以表示所有数, 没有1的话, 最小的正整数就是1
代码:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <fstream>
13 #include <iterator>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define LL long long
18 #define MAXN 1000010
19 #define MOD 1000000007
20 #define eps 1e-6
21 int n;
22
23 int main()
24 {
25 bool flag = false;
26 scanf("%d",&n);
27 for(int i = 0; i < n; i ++)
28 {
29 int x;
30 scanf("%d", &x);
31 if(x == 1) flag = true;
32 }
33 printf("%d\n",flag? -1 : 1);
34 return 0;
35 }
36
Problem_B:
题意:
给三个矩形a, b, c。 问是否能将b和c放入a中。
思路:
无非四种状态。
1)都横着放。
2)都竖着放。
3)一横一竖。
①¬, 竖的放在横着的下面。
②|-,竖的放在横着的旁边。
4)连接在一起。
①--, 横着连在一起。
②| , 竖着连在一起。
代码如下:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <fstream>
13 #include <iterator>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define LL long long
18 #define MAXN 4
19 #define MOD 1000000007
20 #define eps 1e-6
21 int a[MAXN], b[MAXN];
22 void show()
23 {
24 printf("fuck\n");
25 }
26 bool is_ok()
27 {
28 //1) =
29 if(max(a[1], a[2]) <= a[0] && (b[1] + b[2]) <= b[0]) return true;
30 //2)-- && |
31 if((a[1] + a[2] <= a[0]) && max(b[1], b[2]) <= b[0]) return true;
32 if((a[1] + a[2] <= b[0]) && max(b[1], b[2]) <= a[0]) return true;
33 //3)||
34 if((b[1] + b[2] ) <= a[0] && (max(a[1], a[2]) <= b[0])) return true;
35 //4)|-
36 if((b[1] + a[2] <= a[0]) && ((a[1] >= b[2]? a[1] : b[2]) <= b[0])) return true;
37 if((b[2] + a[1] <= a[0]) && ((a[2] >= b[1]? a[2] : b[1]) <= b[0])) return true;
38 //5)-|
39 if(((a[1] >= b[2]? a[1] : b[2]) <= a[0]) && (b[1] + a[2] <= b[0])) return true;
40 if(((a[2] >= b[1]? a[2] : b[1]) <= a[0]) && (b[2] + a[1] <= b[0])) return true;
41 return false;
42 }
43
44 int main()
45 {
46 for(int i = 0; i < 3; i ++)
47 scanf("%d %d",&a[i], &b[i]);
48 printf(is_ok()?"YES\n":"NO\n");
49 return 0;
50 }
Problem_C:
题意:
给一个内角均为120°的六边形(不一定是正六边形), 问, 能将其分割成多少个单位三角形。
思路:


将这个六边形的平行边延长, 相交于三点, 构成一个三角形, 可以证明这个三角形为等边三角形。
因为六边形内角均为120°, 得到三个红色三角形的两个内角为60°, 所以得大三角形的三个顶角均为60°。
所以, 等边三角形的边长为:(a1 + a2 + a3) = (a1 + a6 + a5) = (a1 + a2 + a6) = (a3 + a4 + a5) =....
三角形每行有f(x)个单位三角形, x为每行底边长.
f(x) = x + x - 1 = 2 * x - 1;
f(1) = 1;
f(x + 1) - f(x) = 2(x + 1) - 1 - (2 * x - 1)
= 2
得, 解为:s(len) = f(1) + f(2) + ... + f(len), len 为等边三角形边长。
=(1 + 2 * x - 1) * x / 2
=x ^ 2
所以, 边长为n 的等边三角形所含单位三角形数为 s(n)。
题目所有的六边形所含单位三角形数为:s(n) - f(a1) - f(a3) - f(a5)。
即, 减去三个角的等边三角形, 剩下的就是六边形所包含的
代码如下:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <fstream>
13 #include <iterator>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define LL long long
18 #define MAXN 7
19 #define MAXM 4000
20 #define MOD 1000000007
21 #define eps 1e-6
22 int a[MAXN];
23 int fac[MAXM];
24 void init()
25 {
26 fac[0] = 1;
27 for(int i = 1; i < MAXM; i++)
28 fac[i] = i * i;
29 }
30
31 int main()
32 {
33 init();
34 for(int i = 1; i <= 6; i ++)
35 scanf("%d",&a[i]);
36 int ans = fac[a[1] + a[2] + a[3]] - fac[a[1]] - fac[a[3]] - fac[a[5]];
37 printf("%d\n",ans);
38 return 0;
39 }
Problem_D:
题意:
给两个字符串a,b, 判断它们是否等价。
等价的定义:
满足下列条件之一的就是等价。
1)a == b
2)将字符串a, 分成两部分长度相等的子串a1, a2, b 分成两部分长度相等的子串b1, b2, 满足下列条件之一
①a1 == b1 并且 a2 == b2
②a1 == b2 并且 a2 == b1
思路:
暴力模拟查找, 也可以hash之后再找, 降低查找的复杂度为O(1)。
队友写了一发hash, 我直接暴力的。
暴力模拟注意string , cin 会超时, 需要用char[] , scanf()。
代码如下:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <fstream>
13 #include <iterator>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define LL long long
18 #define MAXN 2000010
19 #define MOD 1000000007
20 #define eps 1e-6
21 char str_a[MAXN], str_b[MAXN];
22 bool dfs(int pos_a, int pos_b, int len)
23 {
24 if(!strncmp(str_a + pos_a, str_b + pos_b, len)) return true;
25 if(len & 1) return false;
26 int sub_len = len / 2;
27 return (dfs(pos_a , pos_b, sub_len) && dfs(pos_a + sub_len, pos_b + sub_len, sub_len))
28 || (dfs(pos_a + sub_len, pos_b , sub_len) && dfs(pos_a , pos_b + sub_len, sub_len));
29 }
30
31 int main()
32 {
33 scanf("%s %s", str_a, str_b);
34 printf(dfs(0, 0, strlen(str_a)) ? "YES\n" : "NO\n");
35 return 0;
36 }
Problem_E:
题意:
给一个h*w的棋盘, 只能往右走, 往下走, 有n个黑格子, 黑格子不能走,问从左上角走到右下角有多少种方案数。
思路:
组合数学书上的一个例题,原题只是背景不同。
这里利用减法原理, 求出所有经过黑格子的方案数, 再用总的方案数减去就得到答案。
sum = C(h - 1 + w - 1, h - 1)
设dp[i] 为从左上角不经过任何黑格子走到第i个黑格子的方案数,
dp[i] = C(x[i] - 1 + y[i] - 1, x[i] - 1) - sigma(x[j] <= x[i] && y[j] <= y[i]) dp[j] * C(x[i] - x[j] + y[i] - y[j], x[i] - x[j])
红色部分为(1,1)到(x[i],y[[i])这个矩形区域内, 经过黑格子到(i,j)的方案数。
则经过第i个黑格子到达右下角的方案数为:dp[i] * C(h - x[i] + w - y[i], w - [i])。
再用sum 减去所有的dp[i]即可。
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define MAXN 2020
#define MAXM 500010
#define MOD 1000000007
#define eps 1e-6
int w, h, n;
LL dp[MAXN];
LL fac[MAXM], fack[MAXM];
struct node
{
int x;
int y;
};
struct node f[MAXN];
bool cmp(struct node x, struct node y)
{
if(x.x == y.x) return x.y < y.y;
return x.x < y.x;
}
LL qpow(LL x, LL k)
{
LL res = ;
while(k)
{
if(k & ) res = res * x % MOD;
x = x * x % MOD;
k >>= ;
}
return res;
}
LL C(LL n, LL m)
{
if(m < || m > n) return ;
return fac[n] * fack[m] % MOD * fack[n-m] % MOD;
}
void init()
{
fac[] = fack[] = fac[] = fack[] = ;
for(int i = ; i < MAXM; i ++)
{
fac[i] = fac[i-] * i % MOD;
fack[i] = qpow(fac[i], MOD - );
}
} int main()
{
init();
scanf("%d %d %d", &h, &w, &n);
for(int i = ; i < n; i ++)
scanf("%d %d",&f[i].x, &f[i].y);
memset(dp, , sizeof(dp));
sort(f, f + n, cmp);
//ans = C(h + w - 2, h - 1)
//dp[i] = C(f[i].x + f[i].y - 2, f[i].x - 1) - dp[j] * C(f[i].x - f[j].x + f[i].y - f[j].y, f[i].x - f[j].x)
//ans -= dp[i] * C(h - f[i].x + w - f[i].y, h -f[i].x)
LL ans = C(h + w - , h - );
for(int i = ; i < n; i ++)
{
dp[i] = C(f[i].x + f[i].y - , f[i].x - );
for(int j = ; j < i; j ++)
if(f[j].x <= f[i].x && f[j].y <= f[i].y)
{
dp[i] -= (dp[j] * C(f[i].x - f[j].x + f[i].y - f[j].y, f[i].x - f[j].x));
dp[i] = (dp[i] + MOD) % MOD;
}
ans = ((ans - (dp[i] * C(h - f[i].x + w - f[i].y, h - f[i].x))) % MOD + MOD) % MOD;
}
printf("%I64d\n", ans);
return ;
}
Codeforces Round #313 (Div. 2)的更多相关文章
- Codeforces Round #313 (Div. 1)
官方英文题解:http://codeforces.com/blog/entry/19237 Problem A: 题目大意: 给出内角和均为120°的六边形的六条边长(均为正整数),求最多能划分成多少 ...
- dp - Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
Gerald and Giant Chess Problem's Link: http://codeforces.com/contest/559/problem/C Mean: 一个n*m的网格,让你 ...
- Codeforces Round #313 (Div. 1) B. Equivalent Strings
Equivalent Strings Problem's Link: http://codeforces.com/contest/559/problem/B Mean: 给定两个等长串s1,s2,判断 ...
- Codeforces Round #313 (Div. 1) A. Gerald's Hexagon
Gerald's Hexagon Problem's Link: http://codeforces.com/contest/559/problem/A Mean: 按顺时针顺序给出一个六边形的各边长 ...
- Codeforces Round #313 (Div. 2)B.B. Gerald is into Art
B. Gerald is into Art Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/ ...
- Codeforces Round #313 (Div. 2) D. Equivalent Strings
D. Equivalent Strings Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/559/ ...
- Codeforces Round #313 (Div. 2) C. Gerald's Hexagon 数学
C. Gerald's Hexagon Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/559/pr ...
- Codeforces Round #313 (Div. 2) A. Currency System in Geraldion
A. Currency System in Geraldion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/co ...
- Codeforces Round #313 (Div. 2) E. Gerald and Giant Chess (Lucas + dp)
题目链接:http://codeforces.com/contest/560/problem/E 给你一个n*m的网格,有k个坏点,问你从(1,1)到(n,m)不经过坏点有多少条路径. 先把这些坏点排 ...
- Codeforces Round #313 (Div. 1) B. Equivalent Strings DFS暴力
B. Equivalent Strings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/559 ...
随机推荐
- oracle17 视图
oracle的视图 介绍 视图是一个虚拟表是一个表,其内容由查询定义,同真实的表一样,视图包含一系列带有名称的列和行数据.但是,视图并不在数据库中以存储的数据值集形式存在(视图不实际存在).行和列数据 ...
- Mysql : L闪存卡linux中的内核参数设置
将 Nytro WarpDrive 加速卡配置为文件系统 本节说明的操作使您可调整 Nytro WarpDrive 加速卡,增强使用 Oracle Linux with Unbreakable Ent ...
- The content of element type "beans" must match "(description?,(import|alias|bean)*)
The content of element type "beans" must match "(description?,(import|alias|bean)*) - ...
- Linux学习笔记总结--配置iptables防火墙
将原有的iptables 文件保存一份 cp -p /etc/sysconfig/iptables /etc/sysconfig/iptables.bak 清空现有的规则 iptables -F ip ...
- 所有Mac用户都需要知道的9个实用终端命令行<转>
转自 http://www.macx.cn/thread-2075903-1-1.html 通常情况下,只有高端用户才会经常用到终端应用.这并不意味着命令行非常难学,有的时候命令行可以轻松.快速的解决 ...
- 使用Android Studio时so文件打包不到APK中
1,需要在build中添加如下配置,这是必备的 Android { sourceSets { main { jniLibs.srcDirs = ['libs'] ...
- SQL Server备份还原数据库中的小把戏
备份数据库时出现一个不太了解的错误 ,错误信息“is formatted to support 1 media families, but 2 media families are expected ...
- 【转】发布iOS应用程序到苹果APP STORE完整流程
原文: http://www.cnblogs.com/JuneWang/p/3850859.html 可以为每个app上传5张截图,虽然至少需要上传一张,可能很少有人会只上传一张图片.另外,你还需要分 ...
- 3 委托、匿名函数、lambda表达式
委托.匿名函数.lambda表达式 在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法.C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方 ...
- PL/SQL常见设置--Kevin的专栏
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...