Codeforces Round #361 div2
ProblemA(Codeforces Round 689A):
题意:
给一个手势, 问这个手势是否是唯一。
思路:
暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 10
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
int n;
int row[MAXN] = {, , , , , , , , , };
int col[MAXN] = {, , , , , , , , , };
int dir[][] = {{-, }, {, }, {, -}, {, }};
char str[MAXN]; bool move_one_step(int d)
{
for(int i = ; i < n; i ++)
{
int x = str[i] - '';
if((d == || d == ) && x == ) return false;
if(row[x] + dir[d][] < || col[x] + dir[d][] < || col[x] + dir[d][] > )
return false;
if(x != && (row[x] + dir[d][] > ))
return false;
}
return true;
} void get_ans()
{
bool flag = false;
for(int d = ; d < ; d ++)
{
if(move_one_step(d)) flag = true;
}
printf(flag ? "NO\n" : "YES\n");
} int main()
{
scanf("%d", &n);
scanf("%s", str); get_ans();
return ;
}
Problem_B(Codeforces Round 689B):
题意:
有n个城市, 第i个城市到第j个城市需要消耗abs(i - j)的能量, 然后每个城市可以转移到另一个城市, 只需要一个能量, 转移是单向的。
问从第一个城市到各个城市所需要的最少能量。
思路:
每次只有三个选择, 即(1、向左走一步, 2、向右走一步, 3、移动到另一个城市)。
以第一个城市为起点, bfs一遍, 即可得到从第一个城市到所有城市所需要的最少能量。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 200010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
int n;
int a[MAXN];
int step[MAXN];
bool vis[MAXN]; void update(int pos)
{
for(int i = pos + ; i <= n; i ++)
step[i] = min(step[i], step[pos] + (i - pos));
for(int i = ; i < pos; i ++)
step[i] = min(step[i], step[pos] + pos - i);
} void show()
{
for (int i = ; i <= n; i ++)
printf("%d ", step[i]);
printf("\n");
} void bfs()
{
queue <int> Q;
Q.push();
step[] = ;
while (!Q.empty())
{
int cnt = Q.front();
Q.pop(); if(vis[cnt]) continue; vis[cnt] = true; //left
if(step[cnt - ] > step[cnt] + && cnt - > )
{
step[cnt - ] = step[cnt] + ;
if(!vis[cnt - ])
Q.push(cnt - );
} //right
if(step[cnt + ] > step[cnt] + && cnt + <= n)
{
step[cnt + ] = step[cnt] + ;
if(!vis[cnt + ])
Q.push(cnt + );
} //move
if(a[cnt] != cnt)
{
if(step[a[cnt]] > step[cnt] + )
{
step[a[cnt]] = step[cnt] + ;
if(!vis[a[cnt]])
Q.push(a[cnt]);
}
}
}
} int main()
{
scanf("%d", &n);
mes(vis, false);
mes(step, 0x3f);
for (int i = ; i <= n; i ++)
{
scanf("%d", &a[i]);
// step[i] = i - 1;
} bfs();
show();
return ;
}
Problen_C(Codeforces Round 689C):
题意:
有四个小偷, 假设第一个小偷偷了a块巧克力, 那么第二个小偷则偷了a*k块, 第三个a*k*k块,第四个a*k*k*k个。
然而所有小偷的背包都有一个容量n, 现在给你一个m, 表示小偷们恰好有m种可能偷法。
求满足上述条件的n, n为恰好满足上述条件的最大的背包容量n, 要使得n尽可能的小。
思路:
最值最大/小化, 典型的二分。
由于a, k, n 都是未知的, 先来看一下它们的关系:
第四个小偷偷到a*k^3块巧克力, 是四个小偷里偷到的最多的。
假设现在已知n, 那么如果n/(x^3) > 0, 说明这个x是一个满足条件的k。
然后再看a, a = n / (x^3), 那么从1 ~ a 条件n/(x^3)都是成立的。
所以, 当k = x时, 有n/(x^3)种方案。
那么, 可以知道, 如果n已知, 则可以求出其方案数。
这里就可以二分n, 找到一个满足的n, 然后在这个范围内去找到最小的n.
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x7ffffffffffffff
#define MOD 1000000007
#define eps 1e-6
#define MAXN 1000010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
LL m; LL check(LL n)
{
LL sum = ;
for (LL i = ; ; i ++)
{
if (n < i * i * i) return sum; sum = sum + n / (i * i * i);
}
return sum;
} LL get_ans(LL &mid)
{
LL l = , r = INF;
LL num = ; while (l < r)
{
mid = (l + r + ) / ;
num = check(mid);
if (num == m) return num;
if (num > m) r = mid - ;
else l = mid + ;
}
return num == m ? num : -;
} int main()
{
scanf("%lld", &m);
LL n = , mid;
LL m1 = get_ans(mid);
if(m1 != m) printf("-1\n");
else
{
for(LL i = ; ; i ++)
{
if(i * i * i > mid) break;
n = max(n, mid / (i * i * i) * (i * i * i));
}
printf("%lld\n", n);
}
return ;
}
Problem_D(CodeForces 689D):
题意:
有两个长度为n的数列a, b。
找出下列子序列的个数:
在[l, r]这个区间内, a数列的最大值 == b数列的最小值。
思路:
求最大最小值, 可以用RMQ, 线段树。
又不涉及修改, 可以使用RMQ, 查询为O(1), 预处理复杂度为O(nlogn)
先将a, b 数列进行处理。
然后, 枚举左端点, 然后再找到满足条件的 右端点的范围, 计算求和即可。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 200010
#define MAXM 21
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
int n;
int a[MAXN], b[MAXN];
int mx_a[MAXN][MAXM], mi_b[MAXN][MAXM];
int p[MAXM], flog[MAXN]; void init()
{
p[] = , flog[] = -;
for(int i = ; i < MAXM; i ++) p[i] = * p[i - ];
for(int i = ; i <= n; i ++) flog[i] = (i & (i - )) ? flog[i - ] : (flog[i - ] + ); for(int i = ; i <= n; i ++) mx_a[i][] = a[i];
for(int j = ; j < MAXM; j ++)
for(int i = ; i <= n; i ++)
if(i + p[j] - <= n)
mx_a[i][j] = max(mx_a[i][j - ], mx_a[i + p[j - ]][j - ]); for(int i = ; i <= n; i ++) mi_b[i][] = b[i];
for(int j = ; j < MAXM; j ++)
for(int i = ; i <= n; i ++)
if(i + p[j] - <= n)
mi_b[i][j] = min(mi_b[i][j - ], mi_b[i + p[j - ]][j - ]);
} int get_mx_a(int l, int r)
{
int k = flog[r - l + ];
return max(mx_a[l][k], mx_a[r - p[k] + ][k]);
} int get_mi_b(int l, int r)
{
int k = flog[r - l + ];
return min(mi_b[l][k], mi_b[r - p[k] + ][k]);
} int min_l(int pos)
{
int l, r, mid;
l = pos - , r = n + ;
while(r - l > )
{
mid = (l + r) >> ;
if(get_mx_a(pos, mid) >= get_mi_b(pos, mid)) r = mid;
else l = mid;
}
return r;
} int max_r(int pos)
{
int l, r, mid;
l = pos - , r = n + ;
while(r - l > )
{
mid = (l + r) >> ;
if(get_mx_a(pos, mid) > get_mi_b(pos, mid)) r = mid;
else l = mid;
}
return r;
} int main()
{
scanf("%d", &n);
for(int i = ; i <= n; i ++)
scanf("%d", &a[i]);
for(int i = ; i <= n; i ++)
scanf("%d", &b[i]); init(); LL ans = ;
for(int i = ; i <= n; i ++)
{
int l = min_l(i);
int r = max_r(i);
ans = ans + (r - l);
}
printf("%I64d\n", ans);
return ;
}
Problem_E(CodeForces 689E):
题意:
f([l, r])表示区间[l, r]内元素个数:r - l + 1
现在给n个区间, 求这n个区间任选k个, 将其求交集运算后的f值。
求出所有情况的f值之和。
思路:
先考虑每个点, 假设已知这个点被x个区间覆盖, 那么, 这个点被计算的次数就是C(x, k)次。
求出所有点的情况即可。 再拓展一下, 如果连续y个点的覆盖数是一样的, 那么就可以得出这y个点被计算的总次数是 y * C(x, k)
利用求前缀和的思路来处理这个点, 左右端点+-1.
这里左端点-1 其实是将整个区间往前移动了一下, 相当于是从0开始。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 200010
#define MAXM 100
#define dd {cout<<"debug"<<endl;}
#define pa {system("pause");}
#define p(x) {printf("%d\n", x);}
#define pd(x) {printf("%.7lf\n", x);}
#define k(x) {printf("Case %d: ", ++x);}
#define s(x) {scanf("%d", &x);}
#define sd(x) {scanf("%lf", &x);}
#define mes(x, d) {memset(x, d, sizeof(x));}
#define do(i, x) for(i = 0; i < x; i ++)
#define dod(i, x, l) for(i = x; i >= l; i --)
#define doe(i, x) for(i = 1; i <= x; i ++)
LL n, k;
LL f[MAXN];
LL fac[MAXN], fack[MAXN];
map <LL, LL> mp;
vector <LL> v; LL qpow(LL x, LL k)
{
LL res = ;
while(k)
{
if(k & ) res = res * x % MOD;
x = x * x % MOD;
k >>= ;
}
return res;
} LL inv(LL a, LL x)
{
return qpow(a, x - );
} LL C(LL n, LL m)
{
if(n < m || m < ) return ;
return ((fac[n] * fack[n - m] % MOD) * fack[m]) % MOD;
} void init()
{
fac[] = fack[] = ;
for(int i = ; i < MAXN; i ++)
{
fac[i] = (fac[i - ] * i) % MOD;
fack[i] = inv(fac[i], MOD);
}
mp.clear();
v.clear();
} int main()
{
init();
LL l, r;
scanf("%lld %lld", &n, &k);
for(int i = ; i <= n; i ++)
{
scanf("%lld %lld", &l, &r);
mp[l - ] ++;
v.push_back(l - ); mp[r] --;
v.push_back(r);
} sort(v.begin(), v.end()); LL ans = , num = , pre_pos = - 1e9 - , cnt_pos, len;
int vlen = v.size();
for(int i = ; i < vlen; i ++)
{
cnt_pos = v[i];
len = cnt_pos - pre_pos;
if(num >= k)
ans = (ans + len * C(num, k) % MOD) % MOD;
if(pre_pos != cnt_pos)
{
pre_pos = cnt_pos;
num = num + mp[cnt_pos];
}
}
printf("%lld\n", ans);
return ;
}
Codeforces Round #361 div2的更多相关文章
- Codeforces Round #539 div2
Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...
- 【前行】◇第3站◇ Codeforces Round #512 Div2
[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...
- Codeforces Round#320 Div2 解题报告
Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...
- Codeforces Round #564(div2)
Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...
- ST表入门学习poj3264 hdu5443 hdu5289 codeforces round #361 div2D
ST算法介绍:[转自http://blog.csdn.net/insistgogo/article/details/9929103] 作用:ST算法是用来求解给定区间RMQ的最值,本文以最小值为例 方 ...
- Codeforces Round #626 Div2 D,E
比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...
- CodeForces Round 192 Div2
This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...
- Codeforces Round #359 div2
Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...
- Codeforces Round #360 div2
Problem_A(CodeForces 688A): 题意: 有d天, n个人.如果这n个人同时出现, 那么你就赢不了他们所有的人, 除此之外, 你可以赢他们所有到场的人. 到场人数为0也算赢. 现 ...
随机推荐
- Linux学习之路:shell变量(二)环境变量
1.env (environment 的缩写)和export显示所有环境变量 2. 环境变量说明 环境变量 意义 HOME 用户主文件夹相当于“~” SHELL Linux默认为/bin/bash H ...
- linux版本的区分
linux每个版本有好几种方式,刚学习的时候还不明白,了解了一下终于知道了 如下,以CentOS为例 1.CentOS系统镜像有两个,安装系统只用到第一个镜像即CentOS-6.x-i386-bin- ...
- HTTP层 —— CSRF保护
简介 跨站请求伪造是一种通过伪装授权用户的请求来利用授信网站的恶意漏洞.Laravel 使得防止应用遭到跨站请求伪造攻击变得简单. Laravel 自动为每一个被应用管理的有效用户会话生成一个 CSR ...
- oracle11g安装成功
- C#学习笔记11:C#中的顺序结构、分支结构、循环结构
顺序结构: 代码从Main()函数开始运行,从上到下,一行一行的执行,不漏掉代码. Int a=6; int b=5; int c=a+b; Console.Write(c); 分支结构: 代码有可能 ...
- php连接Access数据库的三种方法
http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2009/1115/3524.html 虽然不是一个类但先放这儿吧 最近想把一个asp的网站改成 ...
- 修改ckeditor/ckfinder上传文件文件夹 路径以日期格式命名
修改/ckfinder/config.ascx文件: string dateDir = DateTime.Today.ToString("yyyyMM/"); ResourceTy ...
- while循环语句
while(循环条件,返回布尔类型) { 代码执行的操作,或者打印输出. } do whilw循环 do { ...
- 第十二篇、高度自适应的textView
高度根据输入内容变化输入框,我们在很多的应用上都可以见到,如微信.QQ聊天,QQ空间评论等等,该输入框可以用xib,纯代码编写,但是个人觉得纯代码编写用起来更加方便一些. 1.使用自定义的UIView ...
- 使用FreeMarker生成静态HTML
1.FreeMarker需要添加的Maven依赖: <dependency> <groupId>org.freemarker</groupId> <artif ...