2017百度之星初赛b
来源:互联网 发布:gcf软件 编辑:程序博客网 时间:2024/05/17 04:19
题目链接
01:http://acm.hdu.edu.cn/showproblem.php?pid=6114
02:http://acm.hdu.edu.cn/showproblem.php?pid=6115
03:http://acm.hdu.edu.cn/showproblem.php?pid=6116
04:http://acm.hdu.edu.cn/showproblem.php?pid=6117
05:http://acm.hdu.edu.cn/showproblem.php?pid=6118
06:http://acm.hdu.edu.cn/showproblem.php?pid=6119
一些题解
01 Chess
题意说是要找在n*m的棋盘上最多的车让他们互相不攻击,并且下一行的车要在上一行的车的右边,问摆放的方案数。
那么一共就有min(n, m)个车,一共有max(n, m)个位置则答案就是Cmax(n, m)min(n, m)。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const LL maxn(1000005), mod(1e9 + 7);LL Jc[maxn];void calJc() //求maxn以内的数的阶乘{ Jc[0] = Jc[1] = 1; for(LL i = 2; i < maxn; i++) Jc[i] = Jc[i - 1] * i % mod;}/*//拓展欧几里得算法求逆元void exgcd(LL a, LL b, LL &x, LL &y) //拓展欧几里得算法{ if(!b) x = 1, y = 0; else { exgcd(b, a % b, y, x); y -= x * (a / b); }}LL niYuan(LL a, LL b) //求a对b取模的逆元{ LL x, y; exgcd(a, b, x, y); return (x + b) % b;}*///费马小定理求逆元LL pow(LL a, LL n, LL p) //快速幂 a^n % p{ LL ans = 1; while(n) { if(n & 1) ans = ans * a % p; a = a * a % p; n >>= 1; } return ans;}LL niYuan(LL a, LL b) //费马小定理求逆元{ return pow(a, b - 2, b);}LL C(LL a, LL b) //计算C(a, b){ return Jc[a] * niYuan(Jc[b], mod) % mod * niYuan(Jc[a - b], mod) % mod;}int main(){ int t; scanf("%d", &t); int n, m; calJc(); while(t--) { scanf("%d%d", &n, &m); printf("%d\n", C(max(n, m),min(n, m))); } return 0;}
06 小小粉丝度度熊
题意很简单,给定n个区间,每个区间有L-R已经被覆盖,给定m个填充剂每一个可以覆盖一个数,问最能连续覆盖多少个数。
直接合并连续或相交的区间再根据区间开始的数由大到小排序。然后跑一遍记录当前消耗和当前连续数,当消耗的填充剂大于m就把当前首部区间去掉。然后每次比较最大值就可以了。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define rep(i, s, t) for(int i = s;i <= t;i++)#define rap(i, s, t) for(int i = s;i >= t;i--)using namespace std;struct Node{ long long st, en;}node[100004];struct Bag{ long long st, en;}beg[100004];long long n, m;int cmp(Node a, Node b){ return a.st < b.st;}int main(){ while(scanf("%I64d%I64d", &n, &m) != EOF) { rep(i, 1, n) scanf("%I64d%I64d", &node[i].st, &node[i].en); sort(node + 1, node + 1 + n, cmp); int cnt = 0; int xen = 0; rep(i, 1, n){ if(node[i].st <= xen&&i != 1){ if(node[i].en <= xen) continue; else { beg[cnt].en = node[i].en; xen = node[i].en; } } else { beg[++cnt].en = node[i].en; xen = node[i].en; beg[cnt].st = node[i].st; } } long long xh = 0; long long ans = 0; int beginn = 1; for(int i = 1;i <= cnt;i++){ if(i != 1){ int lsxh = beg[i].st - beg[i - 1].en - 1; xh += lsxh; } while(xh > m) { xh -= beg[beginn + 1].st - beg[beginn].en - 1; beginn++; } ans = max(ans, beg[i].en - beg[beginn].st + 1 + m - xh); } printf("%I64d\n", ans); } return 0;}
补题
02 Factory
暴力加LCA把所有配对全部加入查询,然后标记问题序号,注意这里不能用公共祖先数组作为距离树根变去除,因为有可能这两个点相同且没有后继即ancestor数组不会更新,那么只有在并查集合并的时候把子树的标记用父数代替,不能像以前这样随意了233333.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>#define rep(i, s, t) for(int i = s;i <= t;i++)#define rap(i, s, t) for(int i = s;i >= t;i--)#define inf 0x3f3f3f3fusing namespace std;int n, m;const int M = 100004;vector<int>tree[M];vector<int>query[M];vector<int>queid[M];vector<int>worth[M];vector<int>G[M];bool vis[M];int f[M];//int ancestor[M];int dis[M];int ans[M];int Q;int findd(int x){ return x == f[x]?f[x]:f[x] = findd(f[x]);}void uni(int x, int y){ x = findd(x); y = findd(y); if(x != y) f[y] = x;}void init(){ rep(i, 0, n){ G[i].clear(); vis[i] = false; tree[i].clear(); query[i].clear(); worth[i].clear(); queid[i].clear(); f[i] = i; dis[i] = 0; ans[i] = inf; }}void input_tree(){ rep(i, 1, n - 1){ int a, b, c; scanf("%d%d%d", &a, &b, &c); tree[a].push_back(b); worth[a].push_back(c); tree[b].push_back(a); worth[b].push_back(c); }}void input_query(){ scanf("%d", &Q); rep(i, 1, Q) { int a, b; scanf("%d%d", &a, &b); rep(j, 0, (int)G[a].size() - 1) { rep(k, 0, (int)G[b].size() - 1) { query[G[a][j]].push_back(G[b][k]); queid[G[a][j]].push_back(i); query[G[b][k]].push_back(G[a][j]); queid[G[b][k]].push_back(i); } } }}void tarjan(int x, int value){ dis[x] = value; vis[x] = true; rep(i, 0, (int)tree[x].size() - 1){ int v = tree[x][i]; if(vis[v] == true) continue; tarjan(v, value + worth[x][i]); uni(x, v); //ancestor[findd(x)] = x; } rep(i, 0, (int)query[x].size() - 1){ int v = query[x][i]; if(vis[v]&&ans[queid[x][i]] > dis[x] + dis[v] - 2 * dis[findd(v)]) ans[queid[x][i]] = dis[x] + dis[v] - 2 * dis[findd(v)]; //printf("%d %d %d %d %d %d %d %d\n", x, v, findd(v), dis[x], dis[v], dis[findd(v)], queid[x][i], ans[queid[x][i]]); }}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); input_tree(); rep(i, 1, m){ int a; scanf("%d", &a); rep(j, 1, a){ int b; scanf("%d", &b); G[i].push_back(b); } } input_query(); tarjan(1, 0); rep(i, 1, Q) printf("%d\n", ans[i]); } return 0;}
阅读全文
0 0
- 2017百度之星初赛b
- 2017百度之星初赛(B)1001Chess------hdu6114
- 2017 百度之星 初赛B轮 HDU6114 HDU6118 HDU6119
- 2017百度之星初赛(B)-1001Chess
- 2017百度之星初赛B场总结
- 2017百度之星初赛:B-1001. Chess
- hdu6114 2017"百度之星"初赛(B)1001Chess(dp)
- 2017百度之星初赛B-1002(HDU-6115)
- Chess(百度之星初赛B)
- 百度之星初赛B 1002 Factory
- 2017百度之星初赛
- 2017百度之星初赛
- 2012百度之星初赛第一场B题
- 【百度之星】初赛第二场:B网页聚类
- 【2012百度之星/初赛下】B:网页聚类
- 百度之星2012初赛Day2 B - 度度熊的礼物
- hdu 4832 百度之星初赛二B
- 百度之星初赛B——Chess
- Java HashMap工作原理及实现
- 3Sum问题
- HihoCoder
- git删除远程仓库的文件或目录
- [Leetcode] largest rectangle in histogram 直方图中最大的矩形
- 2017百度之星初赛b
- java 中类的加载顺序
- 【并查集入门专题1】E
- JSON.parse和JSON.stringify方法
- tornado页面展示问题
- hdu 6083度度熊的午饭时光(DP+输出路径)
- 八、网易2017<彩色的砖块>
- 英语语法基础_限定词
- codeforces 584D(哥德巴赫猜想)