【套题】2015ACM/ICPC亚洲区长春站 HDU5532 5533 5534 5536 5538
2015-11-07 17:55
585 查看
水几个题,熟悉一下键盘。。。
HDU5532 Almost Sorted ArrayHDU5532\ Almost\ Sorted\ Array
题意:ASAASA定义为,仅去掉一个(One and Only OneOne\ and\ Only\ One)元素后数组是非降序或者非升序。
题解:很明显,判断一个序列是否有序可以通过判断其Longest NonDecreasing SubsquenceLongest\ NonDecreasing\ Subsquence或者Longest NonIncreasing SubsquenceLongest\ NonIncreasing\ Subsquence是否等于序列长度来得到。
HDU5233 Dancing Stars on MeHDU5233\ Dancing\ Stars\ on\ Me
题意:求一堆点是否构成一个正nn边形
题解:求凸包,判断一下→\to
凸包顶点个数是否为nn
凸包所有边是否等长
HDU5534 Partial TreeHDU5534\ Partial\ Tree
题意:nn个点连成一棵树,对某个顶点vv,若其度为degv{deg}_{v},则价值为fdegvf_{{deg}_{v}}
题解:nn个点,n−1n-1条边,共有2∗n−22*n-2个度需要分配。可以证明,首先对每个顶点赋一个度,将剩余的n−2n-2个度任意分配给剩下的顶点,均可以得到一棵树。我们可以简单地反证一下~
对每个顶点,最少可能分配到11个度,最多可能分配到1+(n−2)=n−11+(n-2)=n-1个度,这是满足任意一个顶点的度的限制条件1≤degv≤n−11\le {deg}_{v}\le {n-1}的。
2∗n−22*n-2个度分配完后,我们可以开始两两顶点连边,每连一条边,二者的度分别减11,先不考虑是否会造成环,那么
① 当仅剩22个度时,将对应的两个点连一条边,即完成连边
② 当多余22个度时,假设剩余kk个度,只需要任意选择两个度还没用完的点连接起来,就可以达到度剩余k−2k-2的局面
由①②可知, 恰好可以连出2∗n−22=n−1{{2*n-2}\over{2}}={n-1}条边。此时,根据我们开始的分配,没有任何一个点是没有连至少一条边的,于是不可能存在孤立顶点;另外,,,,窝好像不能证明整个图的连通性鸭(;′⌒`)。。。
于是可以换一个方向考虑,窝们考虑一个放射形图案,一个点度为n−1n-1,作为根,其他所有点都是它的孩子,此时为1+1+⋯+(n−1)1+1+\dots +\left(n-1\right)的组合,将一个点拿下,连到其它点上,变成1+1+⋯+2+(n−2)1+1+\dots+2+\left(n-2\right)的组合,相当于最后的n−2n-2个度分了11个出去,如此下去,可以达到将n−2n-2分解的任何一种组合。
题解续:做完上述分析,我们就可以先考虑一个简化版本了。容量为n−2n-2的背包,有n−1n-1件物品,分别为大小为ii,价值为fif_i,有无限多个,问装满背包最大获得价值为多少。
HDU5536 Chip FactoryHDU5536\ Chip\ Factory
题意:问最大的(si+sj)⊕sk\left({s_i}+{s_j}\right) \oplus {s_k}
题解:将所有数归一化为32 bit32\ bit的串,建立TrieTrie树求解即可。复杂度log(n2)∗nlog(n^2)*n
HDU5538 House BuildingHDU5538\ House\ Building
题意:一坨物体放在地上,求表面积,当然,是放在地上,底面就不算。。。
题解:考虑每个方块的顶面,以及四个侧面即可(如对右侧面,计入的面积应为max(0,ai,j+1−ai,j)max(0, a_{i,{j+1}}-a_{i,j})),其中顶面面积恒为1。注意考虑该方块不存在时的情况,此时顶面面积为0。
HDU5532 Almost Sorted ArrayHDU5532\ Almost\ Sorted\ Array
题意:ASAASA定义为,仅去掉一个(One and Only OneOne\ and\ Only\ One)元素后数组是非降序或者非升序。
题解:很明显,判断一个序列是否有序可以通过判断其Longest NonDecreasing SubsquenceLongest\ NonDecreasing\ Subsquence或者Longest NonIncreasing SubsquenceLongest\ NonIncreasing\ Subsquence是否等于序列长度来得到。
/* ********************************************** File Name: test.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015/11/1 12:34:01 *********************************************** */ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> P; const int INF = 0xfffffff; const int MAX = 100007; int a[MAX]; int dp[MAX]; //dp[i] length is i min int inc(int n) { fill(dp, dp + n + 1, INF); dp[0] = -INF; for (int i = 1; i <= n; ++i) { int sz = upper_bound(dp, dp + i, a[i]) - dp; //printf("get %d\n", sz); dp[sz] = a[i]; } for (int i = n; i >= 1; --i) { if (dp[i] < INF) { return i; } } return 0; } int dec(int n) { reverse(a + 1, a + n + 1); return inc(n); } int main() { int T, n; scanf(" %d", &T); while (T--) { scanf(" %d", &n); for (int i = 1; i <= n; ++i) { scanf(" %d", a + i); } puts((inc(n) >= n - 1 || dec(n) >= n - 1) ? "YES" : "NO"); } return 0; }
HDU5233 Dancing Stars on MeHDU5233\ Dancing\ Stars\ on\ Me
题意:求一堆点是否构成一个正nn边形
题解:求凸包,判断一下→\to
凸包顶点个数是否为nn
凸包所有边是否等长
/* ********************************************** File Name: 5533.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年11月02日 星期一 20时33分46秒 *********************************************** */ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> P; const double INF = FLT_MAX; const double EPS = 1e-8; const double PI = acos(-1.0); const int MAX = 107; inline int sign(double x) { if (fabs(x) < EPS) return 0; if (x > 0.0) return 1; return -1; } struct Point { double x, y; Point() {} Point(double _x, double _y): x(_x), y(_y) {} Point operator-(const Point& ne)const { return Point(x - ne.x, y - ne.y); } Point operator+(const Point& b)const { return Point(x + b.x, y + b.y); } Point operator*(const double t)const { return Point(t * x, t * y); } Point operator/(const double t)const { if (sign(t) == 0) return Point(INF, INF); return Point(x / t, y / t); } double operator^(const Point& b)const { return (x - b.x) * (x - b.x) + (y - b.y) * (y - b.y); } } ping[MAX]; struct Polygon { Point p[MAX]; int n; } ans; inline double xmult(Point o, Point a, Point b) { return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y); } bool cmp(const Point& a, const Point& b) { return a.x < b.x || (sign(a.x - b.x) == 0 && a.y < b.y); } void convex_hull(Point p[MAX], int n, Polygon& res) { res.n = 0; sort(p, p + n, cmp); int i, j, top; for (i = 0, top = 0; i < n; ++i) { while (top > 1 && xmult(res.p[top - 2], res.p[top - 1], p[i]) < EPS) { --top; } res.p[top++] = p[i]; } j = top; for (i = n - 2; i >= 0; --i) { while (top > j && xmult(res.p[top - 2], res.p[top - 1], p[i]) < EPS) { --top; } res.p[top++] = p[i]; } res.n = top - 1; } int main() { int T, n; scanf(" %d", &T); while (T--) { scanf(" %d", &n); for (int i = 0; i < n; ++i) { scanf(" %lf %lf", &ping[i].x, &ping[i].y); } convex_hull(ping, n, ans); if (n < 3 || ans.n != n) { puts("NO"); continue; } double leng = ans.p[0] ^ ans.p[n - 1]; bool flag = true; for (int i = 0; i < n - 1; ++i) { if (sign((ans.p[i] ^ ans.p[i + 1]) - leng)) { flag = false; break; } } puts(flag ? "YES" : "NO"); } return 0; }
HDU5534 Partial TreeHDU5534\ Partial\ Tree
题意:nn个点连成一棵树,对某个顶点vv,若其度为degv{deg}_{v},则价值为fdegvf_{{deg}_{v}}
题解:nn个点,n−1n-1条边,共有2∗n−22*n-2个度需要分配。可以证明,首先对每个顶点赋一个度,将剩余的n−2n-2个度任意分配给剩下的顶点,均可以得到一棵树。我们可以简单地反证一下~
对每个顶点,最少可能分配到11个度,最多可能分配到1+(n−2)=n−11+(n-2)=n-1个度,这是满足任意一个顶点的度的限制条件1≤degv≤n−11\le {deg}_{v}\le {n-1}的。
2∗n−22*n-2个度分配完后,我们可以开始两两顶点连边,每连一条边,二者的度分别减11,先不考虑是否会造成环,那么
① 当仅剩22个度时,将对应的两个点连一条边,即完成连边
② 当多余22个度时,假设剩余kk个度,只需要任意选择两个度还没用完的点连接起来,就可以达到度剩余k−2k-2的局面
由①②可知, 恰好可以连出2∗n−22=n−1{{2*n-2}\over{2}}={n-1}条边。此时,根据我们开始的分配,没有任何一个点是没有连至少一条边的,于是不可能存在孤立顶点;另外,,,,窝好像不能证明整个图的连通性鸭(;′⌒`)。。。
于是可以换一个方向考虑,窝们考虑一个放射形图案,一个点度为n−1n-1,作为根,其他所有点都是它的孩子,此时为1+1+⋯+(n−1)1+1+\dots +\left(n-1\right)的组合,将一个点拿下,连到其它点上,变成1+1+⋯+2+(n−2)1+1+\dots+2+\left(n-2\right)的组合,相当于最后的n−2n-2个度分了11个出去,如此下去,可以达到将n−2n-2分解的任何一种组合。
题解续:做完上述分析,我们就可以先考虑一个简化版本了。容量为n−2n-2的背包,有n−1n-1件物品,分别为大小为ii,价值为fif_i,有无限多个,问装满背包最大获得价值为多少。
/* ********************************************** File Name: 5534.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015/11/3 22:22:19 *********************************************** */ #include <bits/stdc++.h> using namespace std; typedef pair<int, int> P; const int INF = 0xfffffff; const int MAX = 2018; vector<P> bag; int dp[MAX]; int f[MAX]; int m; void push(int weight, int value) { for (int i = 1; i * weight <= m; i <<= 1) { bag.push_back(P(weight * i, value * i)); //printf("push (%d, %d)\n", weight * i, value * i); } } int main() { int T, n; scanf(" %d", &T); while (T--) { bag.clear(); scanf(" %d", &n); m = n - 2; for (int i = 1; i < n; ++i) { scanf(" %d", f + i); } int ans = n * f[1]; for (int i = 2; i < n; ++i) { push(i - 1, f[i] - f[1]); } sort(bag.begin(), bag.end()); unique(bag.begin(), bag.end()); fill(dp, dp + m + 1, -INF); dp[0] = 0; for (int i = 0; i < bag.size(); ++i) { for (int j = m; j >= bag[i].first; --j) { if (dp[j - bag[i].first] + bag[i].second > dp[j]) { dp[j] = dp[j - bag[i].first] + bag[i].second; } } } printf("%d\n", dp[m] + ans); } return 0; }
HDU5536 Chip FactoryHDU5536\ Chip\ Factory
题意:问最大的(si+sj)⊕sk\left({s_i}+{s_j}\right) \oplus {s_k}
题解:将所有数归一化为32 bit32\ bit的串,建立TrieTrie树求解即可。复杂度log(n2)∗nlog(n^2)*n
/* ********************************************** File Name: 5536.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015/11/3 21:38:44 *********************************************** */ #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MAX = 1LL << 32; const int CNT = 1024; int a[CNT]; struct Node { Node* son[2]; int cnt; Node(int _x = 0): cnt(_x) { son[0] = son[1] = NULL; } }; void insert(Node* T, int x) { for (ll ck = MAX; ck > 0; ck >>= 1) { int idx = (x & ck) > 0 ? 1 : 0; if (T->son[idx] == NULL) { T->son[idx] = new Node(); } ++(T->son[idx]->cnt); T = T->son[idx]; } } void remove(Node* T, int x) { for (ll ck = MAX; ck > 0; ck >>= 1) { int idx = (x & ck) > 0 ? 1 : 0; --(T->son[idx]->cnt); T = T->son[idx]; } } void clear(Node* T) { if (T == NULL) { return; } for (int i = 0; i < 2; ++i) { clear(T->son[i]); } delete T; } int gao(Node* T, int x) { int res = 0; for (ll ck = MAX; ck > 0; ck >>= 1) { int idx = (x & ck) > 0 ? 1 : 0; res <<= 1; if (T->son[idx ^ 1] != NULL && T->son[idx ^ 1]->cnt > 0) { T = T->son[idx ^ 1]; res |= idx ^ 1; } else { T = T->son[idx]; res |= idx; } } return res; } int main() { int T, n; scanf(" %d", &T); while (T--) { scanf(" %d", &n); Node* T = new Node(); for (int i = 0; i < n; ++i) { scanf(" %d", a + i); insert(T, a[i]); } int ans = 0; for (int i = 0; i < n; ++i) { remove(T, a[i]); for (int j = 0; j < n; ++j) { if (j == i) continue; remove(T, a[j]); int res = gao(T, a[i] + a[j]); //printf("remove %d, %d, get %d\n", a[i], a[j], res); ans = max(ans, res ^ (a[i] + a[j])); //ans = max(ans, gao(T, a[i] + a[j])); insert(T, a[j]); } insert(T, a[i]); } clear(T); printf("%d\n", ans); } return 0; }
HDU5538 House BuildingHDU5538\ House\ Building
题意:一坨物体放在地上,求表面积,当然,是放在地上,底面就不算。。。
题解:考虑每个方块的顶面,以及四个侧面即可(如对右侧面,计入的面积应为max(0,ai,j+1−ai,j)max(0, a_{i,{j+1}}-a_{i,j})),其中顶面面积恒为1。注意考虑该方块不存在时的情况,此时顶面面积为0。
/* ********************************************** File Name: 5538.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年11月02日 星期一 20时31分00秒 *********************************************** */ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> P; const int MAX = 64; int a[MAX][MAX]; int main() { int T, n, m; scanf(" %d", &T); while (T--) { scanf(" %d %d", &n, &m); memset(a, 0, sizeof(a)); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { scanf(" %d", &a[i][j]); } } int sum = 0; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (a[i][j] > 0) ++sum; sum += max(0, a[i][j] - a[i - 1][j]); sum += max(0, a[i][j] - a[i][j - 1]); sum += max(0, a[i][j] - a[i + 1][j]); sum += max(0, a[i][j] - a[i][j + 1]); } } printf("%d\n", sum); } return 0; }
相关文章推荐
- transient关键字
- .Net Framework 4.0 内部排序探索
- UTF-8,gb2312,GBK的区别
- Google Guava 类库简介
- MySQL的几个用法
- PLA code
- WordPress中修改固定链接导致无法显示文章内容的问题的解决办法
- Android签名有关问题
- android开发的一些概念
- bootstrap
- delphi OleVariant转换RecordSet
- 数值分析 幂法求矩阵A按模最大的特征值和相应的特征向量
- POJ-2501
- 小技巧3-使用Xcode的代码块功能提高编码速度
- 品牌效益
- native跟volatile
- 复数和复函数
- uva512追踪电子表格
- [ubuntu]移动Terminal终端中的TAB标签
- StringUtil