2013 Asia Regional Dhaka 解题报告
来源:互联网 发布:从python开始学编程pdf 编辑:程序博客网 时间:2024/04/30 09:23
Source
Vjudge
UVALive 6650 - UVALive 6660
A 水
B
题意
N个display,每个相当于一个长度为L的B进制的数。开始都是0,每次可以按一个按钮,使得某个display对应位加1。没有进位,所以最多到B-1。且每个数最低位不能按。两个人玩游戏,如果有人按下按钮后使得局面所有数字的和能被3整除,则输。无法移动则平局。问游戏结果。
分析
相当于局面上数字和有模3等于0、1、2的三个状态,按钮相当于之间的边,算算一共有多少边,再分类讨论。假设是m0,m1,m2,分别代表使得数字和增加模3等于0、1、2的按钮有多少次。边界就不讨论了,考虑m0=0,假设m1 < m2,那么先手走m1,之后就是m1-m2-m1-m2 … m1会被耗空,后手只能走m2而负。m1>=m2也类似。考虑有m0,m0如果是偶数个,并没有什么用,因为m0相当于是先后手做一个转换,如果是偶数个,先手做一次m0,后手也可以做一次进而抵消。如果是奇数个,假设m1 < m2,先手可以走m2,给对方留下必胜态,然后再用m0做先手转换让自己必胜。但m1和m2相差不超过2时就不成立了,再讨论一下即可。
代码
/************************************************************************* > File Name: b.cpp > Author: james47 > Mail: > Created Time: Wed Aug 26 10:16:25 2015 ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define F 0#define S 1#define D 2typedef unsigned long long ll;int T, cas = 0;ll m0, m1, m2;char msg[3][5] = {"M", "J", "Draw"};int solve(){ if (m0 == 0 && m1 == 0 && m2 == 0) return D; if (m0 != 0 && m1 == 0 && m2 == 0) return S; if (m1 == 0 || m2 == 0){ if (!m2) swap(m1, m2); if (m2 <= 2) return D; if (m0 % 2 == 0) return S; else return F; } if (m0 % 2 == 0) return F; else{ if (m1 > m2) swap(m1, m2); if (m1 == m2) return S; if (m1 + 1 == m2 || m1 + 2 == m2) return D; return F; }}int main(){ scanf("%d", &T); while(T--){ m0 = m1 = m2 = 0; int n, l, b; scanf("%d", &n); while(n--){ scanf("%d %d", &l, &b); if (b % 3 == 0) m0 += (ll)(l-1) * (b-1); else if (b % 3 == 1) m1 += (ll)(l-1) * (b-1); else{ m2 += (ll)l/2 * (b-1); m1 += (ll)(l-1)/2 * (b-1); } } printf("Case %d: %s\n", ++cas, msg[solve()]); } return 0;}
C
题意
N个点的无向连通图(N <= 100),边有权值,要求选择一部分的边,使得前K个点的度数为奇数,之后的点度数为偶数,求满足条件的最小边权和。
分析
考虑选了一条路径,那么只有端点的度数奇偶性改变。这样我们可以将前K个点通过选取不相交的路径来两两匹配,满足条件。由于边的权值为正,所以我们选的路径肯定不会相交,否则不优。所以floyd预处理点到点最近距离然后跑一般图最大权匹配即可。
根据我多日的检索,一般图最大权匹配应该是要用带权开花树来做的,但是不会写(可以参见15年集训队论文讲图匹配的,或者就是论文啊书啊之类的)。。然后下面这个做法似乎是来自uestc的某位神牛,转化后找图中负环,随机化的做法,不保证最优,复杂度不明,据说1s能跑500点。
代码就不贴了,直接参见这篇吧
http://blog.csdn.net/fipped/article/details/47060931
D 水
E
题意
三类珠子,分别能涂X、Y、Z种颜色,第一种和第三种珠子共有A颗,第二种和第三种共B颗,给A、B、X、Y、Z(均<=10^17),问有多少种不同的珍珠链,结果模1000003
分析
首先肯定要考虑枚举第三种珠子,确定一个长度。结果的式子不难列出:
但是范围太大了,做不了。看了ac代码感觉不明觉厉。然后博哥给我讲了讲,大概明白是怎么一回事。
记 p = 1000003,考虑把i
做p进制分解,由lucas定理我们知道前面的组合数是可以这么拆开再乘起来的,后面的幂次推一推发现也是可以的(i
超过A对应位
代码
/************************************************************************* > File Name: e.cpp > Author: james47 > Mail: > Created Time: Fri Aug 28 15:07:40 2015 ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cassert>#include <algorithm>using namespace std;const int mod = 1000003;typedef long long ll;int T;ll a[mod*2+10], inv[mod*2+10], px[mod+10], py[mod+10], pz[mod+10];inline ll C(ll n, ll m){// assert(n < mod && m < mod && n-m < mod); return a[n] * inv[a[m]] % mod * inv[a[n-m]] % mod;}ll A, B, X, Y, Z;ll solve(ll A, ll B, ll X, ll Y, ll Z){ ll ret = 1; X %= mod, Y %= mod, Z %= mod; px[0] = py[0] = pz[0] = 1; for (int i = 1; i < mod; i++){ px[i] = px[i-1] * X % mod; py[i] = py[i-1] * Y % mod; pz[i] = pz[i-1] * Z % mod; } while(A&&B){ //seems that while(A) is wrong ll a = A % mod, b = B % mod; A /= mod, B /= mod; ll tmp = 0; for (int i = 0; i <= a; i++){ if (i > b) break; (tmp += C(a+b-i, a) * C(a, i) * px[a-i] % mod * py[b-i] * pz[i]) %= mod; } (ret *= tmp) %= mod; } return ret;}void init(){ a[0] = a[1] = 1; inv[1] = 1; for (int i = 2; i < mod*2+5; i++){ a[i] = a[i-1] * i % mod; inv[i] = inv[mod % i] * (mod - mod/i) % mod; }// cout << C(mod+10, 2) << endl;// cout << a[mod+10] * inv[a[2]] % mod * inv[a[mod+8]] << endl;}int main(){ init(); ios::sync_with_stdio(false); cin >> T; while(T--){ cin >> A >> B >> X >> Y >> Z; assert(solve(A, B, X, Y, Z) == solve(B, A, Y, X, Z)); cout << solve(A, B, X, Y, Z) << endl; } return 0;}
F
略 (x, y)逆时针转90度是(-y, x),然后调整即可。更聪明的做法是交换一下位置直接输出~
G
题意
有N个区间[L, R],给M个询问X,对于满足L<=X<=R的区间,求max(min(X-L, R-X))
分析
我们发现一个区间如果被其他区间包含,那么它就没有意义了。。去掉区间的嵌套,然后就发现区间是有管辖的范围,范围内的查询的答案都由它得到,而管辖的范围会是单调的,单调队列一样扫一遍就好了~O(n)哒~更容易想到的做法大概是用set之类的维护,扫的过程中碰到区间的中点然后做插入删除之类的操作。
代码
/************************************************************************* > File Name: g.cpp > Author: james47 > Mail: > Created Time: Wed Aug 26 09:30:13 2015 ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <algorithm>using namespace std;typedef set<pair<int, int> >::iterator sit;const int maxn = (int)1e5+100;int T, n, m, cas = 0;pair<int, int> a[maxn];int b[maxn], c[maxn];bool cmp(const int& x, const int& y){ return b[x] < b[y]; }int main(){ scanf("%d", &T); while(T--){ scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) scanf("%d %d", &a[i].first, &a[i].second); sort(a, a+n); int orin = n, n = 1; for (int i = 1; i < orin; i++){ if (a[i].second <= a[n-1].second) continue; if (a[i].first == a[n-1].first){ a[n-1] = a[i]; continue; } a[n++] = a[i]; }// for (int i = 0; i < n; i++)// printf("%d %d\n", a[i].first, a[i].second); for (int i = 0; i < m; i++){ scanf("%d", b+i); c[i] = i; } sort(c, c+m, cmp); int head = 0, tail = 0; for (int i = 0; i < m; i++){ int x = b[c[i]]; int& ans = b[c[i]] = 0; while(tail < n && a[tail].first <= x) tail ++; while(head < tail && a[head].second < x) head ++; if (head >= tail) continue;// printf("%d %d %d %d %d\n", head, tail, a[head].first, a[head].second, x); ans = min(a[head].second - x, x - a[head].first); while(head+1 < tail){ int tmp = min(a[head+1].second - x, x - a[head+1].first); if (tmp > ans){ ans = tmp; head++; } else break; } } printf("Case %d:\n", ++ cas); for (int i = 0; i < m; i++) printf("%d\n", b[i]); } return 0;}
H
题意
Given an integer N, find how many pairs (A, B) are there such that: gcd(A, B) = A xor B where 1 ≤ B ≤ A ≤ N
分析
考虑A是两者中比较大的数,然后枚举它的因子C作为gcd,则对应的唯一可能的B=A xor C,可以直接判gcd(A, B) == C(先判整除,然后再求gcd,即可通过,见http://blog.csdn.net/firenet1/article/details/47981287)。
而实际上A=pC, B=qC, p > q, 由于
代码
/************************************************************************* > File Name: h.cpp > Author: james47 > Mail: > Created Time: Wed Aug 26 10:49:10 2015 ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn = (int)3e7;int T, cas;long long ans[maxn+100];int main(){ for (int i = 1; i <= maxn; i++) for (int j = i+i; j <= maxn; j += i){ if ((j^(j-i)) == i) ans[j]++; } for (int i = 2; i <= maxn; i++) ans[i] += ans[i-1]; ios::sync_with_stdio(false); cin >> T; while(T--){ int n; cin >> n; cout << "Case " << ++cas << ": " << ans[n] << endl; } return 0;}
I
题意
有一个人用Prim做Dijkstra做的事,请把输入数据做调整使得结果是正确的,输入为N点M边无向连通图,边权为正且互异
分析
用Prim求出了最小生成树,也就得到了起点到各个点的一条路,我们得让最短路刚好落在树上。。。反正就是bfs一下,从小到大赋权值。。
代码不贴了。。
J
挺简单的吧。。略过
K
dancing links。。。待补。。。
- 2013 Asia Regional Dhaka 解题报告
- Regionals 2011, Asia - Dhaka 部分解题报告
- 2013 Asia Regional Changchun 解题报告
- 2013 Asia Regional Contest A题 意外 解题报告
- 2013 Asia Regional Contest C题 解题报告
- Regional 2011, Asia - Kuala Lumpur 解题报告
- Asia Dhaka 2013
- hdu 2013 ACM/ICPC Asia Regional Online —— Warmup解题报告
- 2013 ACM/ICPC Asia Regional Hangzhou Online(解题报告) 正在更新
- hdu 2013 ACM/ICPC Asia Regional Online —— Warmup2解题报告
- 2012 ACM/ICPC Asia Regional Changchun Online 解题报告
- 2012 ACM/ICPC Asia Regional Changchun Online [赛后解题报告]
- 2012 ACM/ICPC Asia Regional Tianjin Online [赛后解题报告]
- 2012 ACM/ICPC Asia Regional Tianjin Online [赛后解题报告]
- 2013 ACM/ICPC Asia Regional Changsha Online - C(Color Representation Conversion)、E (Travelby Bi)解题报告
- 2012 ACM/ICPC Asia Regional Tianjin Online 1006_you are the one 解题报告
- 2012 ACM/ICPC Asia Regional Tianjin Online ——A very hard mathematic problem解题报告
- 2014 Asia Kuala Lumpur Regional Contest(吉隆坡2014)解题报告汇总
- OC 权限修饰符
- Boot process(启动过程)
- iOS本地存储NSUserDefaults2
- callgraph 获取函数的调用栈
- 关于“应用图标更改,但是安装之后,图标未改变”总结
- 2013 Asia Regional Dhaka 解题报告
- mongo slave 无法show dbs
- 浅谈android的selector背景选择器
- 2015/9/9
- thinkphp phpexcel使用
- java应用程序利用Exe4j打包exe文件
- oracle imp exp 命令
- ./runInstaller: /download/database/install/.oui: /lib/ld-linux.so.2: bad ELF interpreter: No such fi
- 小白_最近浏览功能