2012年"新秀杯"程序设计比赛——现场决赛参考题解
2012-11-18 21:40
387 查看
引言:比较简略,还请见谅!能力有限,难免有错,敬请不吝指导 ^_^ ~
比赛链接:http://acm.swjtu.edu.cn/JudgeOnline/showcontest?contest_id=1131
比赛对象:大一、大二
比赛时间:2012年11月18日 12:00——17:00
参考题解:
【A题:推箱子】
对箱子进行广搜,判断箱子的当前状态是否合法,判断合法的方式是,判断人能否从原状态到达箱子的“后面”。
测试数据:
输入
输出
【B题:五子棋】
首先,通过给定的当前状态,判断是哪位棋手下;然后,去枚举判断每一位空位,判断是否可以赢得游戏。
测试数据:
输入:
输出
【C题:24点】
枚举数字和运算符,计算是否存在某一数学表达式值为24即可,可通过回溯法求解。
测试数据:
输入
输出
【D题:水果忍者】
对于任意一个最优切割线,总可以通过平移或旋转得到一条经过某两点的切割线,而且这条切割线仍然是最优切割线。
【E题:中位数】
树状数组,或线段树。
【F题:三角形的个数】
源自浙大月赛,考虑所有子矩形,对于每个子矩形,计算方案数,然后求和。对于每个子矩形,三角形的顶点在矩形边界的格点上,利用锐角性质,通过余弦定理得到格点间的不等式关系。
【G题:又见A+B】
模拟题,没有模出来,可以考虑再模一下。
【H题:K-数组】
排序后,统计计数即可。
【I题:放苹果】
穷举法,这里放有几组输入数据的P值保留到小数点后面2位,似乎并不影响解答试题。
测试数据:
输入
输出
Thank you for your reading!
P.S. 测试数据难免会有差错,敬请指正!个人不推荐短时间内希望得到测试数据,一定程度上,不能提高个人能力。
比赛链接:http://acm.swjtu.edu.cn/JudgeOnline/showcontest?contest_id=1131
比赛对象:大一、大二
比赛时间:2012年11月18日 12:00——17:00
参考题解:
【A题:推箱子】
对箱子进行广搜,判断箱子的当前状态是否合法,判断合法的方式是,判断人能否从原状态到达箱子的“后面”。
测试数据:
输入
22 6 4 0 0 0 1 0 0 0 0 2 4 0 0 0 1 1 1 0 0 0 0 3 0 0 0 6 5 0 0 0 0 0 0 4 0 2 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 3 0 0 0 0 0 5 6 0 0 0 0 0 0 2 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 4 0 0 3 7 5 1 1 4 1 0 0 0 1 1 2 1 0 0 0 3 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 6 6 0 4 1 0 0 0 0 2 0 0 0 0 1 0 1 0 1 1 0 0 1 0 3 0 1 0 0 0 0 0 0 0 0 0 0 0 5 6 0 0 0 3 0 0 1 4 0 1 0 1 2 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 6 6 0 0 0 0 1 0 0 4 0 1 0 0 0 0 0 1 0 0 0 0 1 0 2 0 0 1 0 0 3 0 0 0 1 0 0 0 6 6 0 0 0 0 1 0 0 2 0 1 0 0 0 0 0 1 0 0 0 0 1 0 4 0 0 1 0 0 3 0 0 0 1 0 0 0 5 3 4 0 0 0 0 0 2 0 0 0 0 0 0 0 3 5 3 4 0 0 0 0 2 0 0 0 0 0 0 0 0 3 5 3 4 2 0 0 0 1 1 1 0 1 0 0 3 0 0 5 3 0 1 0 0 0 4 2 0 0 0 0 1 3 1 0 6 6 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 4 0 0 0 0 0 6 6 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 3 0 0 0 0 0 6 6 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 4 2 3 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 6 6 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 3 2 4 0 0 0 1 0 0 0 0 0 1 0 0 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 3 1 1 0 0 0 2 0 0 0 0 0 4 0 0 6 6 0 0 0 4 0 0 0 0 0 2 0 0 1 1 1 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 0 0 0 0 0 4 2 0 1 1 0 1 0 0 0 1 0 0 0 3 1 0 0 0 0 5 3 4 0 0 0 0 2 0 0 0 0 0 0 0 0 3 7 5 1 1 4 1 0 0 0 1 1 2 1 0 0 0 3 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 6 6 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 4 0 0 0 0 0
输出
Case #1: 6 Case #2: -1 Case #3: 7 Case #4: 11 Case #5: 9 Case #6: 3 Case #7: -1 Case #8: -1 Case #9: 4 Case #10: -1 Case #11: -1 Case #12: 4 Case #13: 8 Case #14: 2 Case #15: 1 Case #16: 1 Case #17: 1 Case #18: 1 Case #19: 5 Case #20: -1 Case #21: 11 Case #22: 8
【B题:五子棋】
首先,通过给定的当前状态,判断是哪位棋手下;然后,去枚举判断每一位空位,判断是否可以赢得游戏。
测试数据:
输入:
11 _______________ _______________ _______________ __________b____ _________w_____ ______wbw______ ____bbwwbb_____ __bbwbwbbwb____ ___wwbbwbw_____ _bwwwwbwwwb____ _bwwwwbwbww____ ___wbbw_bbbw___ ____wbbb_______ ______bb_______ _______________ _______________ _______________ _______________ _______________ _______________ ___bbbb________ __w____________ __w____________ __w____________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ ________w______ _____w__b______ ____wbb_bbw____ _______wb______ ________w______ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ ________b______ _____wwwb______ _____wbbbb_____ _______wb______ ________w______ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ w______________ _w______w______ __b____b_______ ___b__b________ ___wb_b________ ___wb__________ __wbw_b________ __www__b_______ _______________ _______________ _______________ _______________ _______________ bbbbw__________ bbbbw__________ wwwwbw_________ ____wbw________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ _______________ ______w________ ______w________ ______w________ ______w________ _______________ _____b_________ ___b_b_b_______ _______________ _______________ _______________ _______________ _______________ _______________ ____w__________ _____w_________ ______w________ _______________ ________w______ _______________ _______________ _____b_________ ___bbbwb_______ _____b_________ _______________ _______________ _______________ _______________ _______________ ____________w__ _______________ __________w____ _________w_____ ________w______ _______________ _______________ _____b_________ ___bbbwb_______ _____b_________ _______________ _______________ _______________ _______________ _______________ _______________ ______b________ ______b________ _______________ ______b________ ___ww_w________ _______________ _______________ _______________ _______________ _______________ _______________ _______________
输出
Case #1: Yes Case #2: No Case #3: No Case #4: Yes Case #5: No Case #6: Yes Case #7: No Case #8: No Case #9: Yes Case #10: Yes Case #11: No
【C题:24点】
枚举数字和运算符,计算是否存在某一数学表达式值为24即可,可通过回溯法求解。
测试数据:
输入
30 4 10 4 10 5 5 5 A 2 7 9 9 2 10 10 10 3 3 3 3 3 3 3 4 3 3 3 5 3 3 3 6 3 3 3 7 3 3 3 8 3 3 3 9 3 3 3 10 3 3 4 4 3 3 4 10 3 3 5 5 3 3 5 8 3 3 6 6 3 3 7 10 3 3 8 8 3 3 9 9 3 3 10 10 3 4 6 7 3 4 8 8 3 4 9 10 3 5 5 5 3 5 5 10 3 5 7 7 3 5 8 10 A A J J A 2 Q Q
输出
Case #1: Yes Case #2: Yes Case #3: No Case #4: No Case #5: Yes Case #6: Yes Case #7: Yes Case #8: Yes Case #9: Yes Case #10: Yes Case #11: Yes Case #12: Yes Case #13: Yes Case #14: No Case #15: Yes Case #16: No Case #17: Yes Case #18: No Case #19: Yes Case #20: Yes Case #21: No Case #22: No Case #23: No Case #24: No Case #25: No Case #26: No Case #27: No Case #28: No Case #29: Yes Case #30: Yes
【D题:水果忍者】
对于任意一个最优切割线,总可以通过平移或旋转得到一条经过某两点的切割线,而且这条切割线仍然是最优切割线。
#include<cstdio> #include<cstring> struct Point { int x, y; Point() {} Point(int _x, int _y) : x(_x), y(_y) {} inline void readin() { scanf("%d %d", &x, &y); } inline Point operator+(const Point &cp) const { return Point(x + cp.x, y + cp.y); } inline Point operator-(const Point &cp) const { return Point(x - cp.x, y - cp.y); } inline int operator*(const Point &cp) const { return x * cp.y - y * cp.x; } }; struct Line { Point s, e; Line() {} Line(Point _s, Point _e) : s(_s), e(_e) {} }; #define Segment Line int isIntersected(Line L, Segment S) { int a = (L.e - L.s) * (S.s - L.e); int b = (L.e - L.s) * (S.e - L.e); return (a * b <= 0); } const int maxN = 10 + 2; int N, K[maxN]; Point P[maxN][maxN]; int nS, Select[maxN]; int gao() { static Point H[maxN * maxN]; int nh = 0; for(int i = 0; i < nS; i++) for(int j = 0; j < K[ Select[i] ]; j++) H[nh ++] = P[ Select[i] ][ j ]; for(int i = 0; i < nh; i++) for(int j = i + 1; j < nh; j++) { int yes = 0; for(int k = 0; k < nS; k++) for(int r = 0; r < K[ Select[k] ]; r++) if( isIntersected(Line(H[i], H[j]), Line(P[Select[k]][r], P[Select[k]][(r + 1) % K[ Select[k] ]])) ) { yes ++; break; } if( yes == nS ) return 1; } return 0; } int main() { freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); int idx = 0, nt; scanf("%d", &nt); while( (nt --) > 0 ) { scanf("%d", &N); for(int i = 0; i < N; i++) { scanf("%d", K + i); for(int j = 0; j < K[i]; j++) P[i][j].readin(); } int ans = 1, up = 0x1 << N; for(int i = 3; i < up; i++) { nS = 0; for(int j = 0; j < N; j++) if( i & (0x1 << j) ) Select[nS ++] = j; if( nS <= ans ) continue; if( gao() ) ans = nS; } printf("Case #%d: %d\n", ++ idx, ans); } return 0; }
【E题:中位数】
树状数组,或线段树。
#include <vector> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <sstream> #include <iostream> #include <cstdio> #include <queue> #include <cmath> #include <cstdlib> #include <cstring> #include <ctime> #include <string> #include <cassert> typedef long long i64d; typedef unsigned long long i64u; using namespace std; template<class T> inline T cAbs(T x) { if( x < 0 ) return -x; return x; } template<class T> inline T cMax(T a, T b) { return a > b ? a : b; } template<class T> inline T cMin(T a, T b) { return a < b ? a : b; } const int maxN = 250000 + 10; const i64d Mod = 65536; i64d A[maxN]; int N, K; int C[65536 + 10]; int lowbit(int x) { return x & (-x); } void update(int pos, int val) { while( pos <= 65536 ) { C[pos] += val; pos += lowbit(pos); } } int query(int pos) { int sum = 0; while( pos > 0 ) { sum += C[pos]; pos -= lowbit(pos); } return sum; } int main() { freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); i64d seed, mul, add; while( scanf("%lld %lld %lld", &seed, &mul, &add) == 3 ) { scanf("%d %d", &N, &K); A[0] = seed; for(int i = 1; i < N; i++) A[i] = (A[i - 1] * mul + add) % Mod; if( K == 1 ) { i64d ans = 0LL; for(int i = 0; i < N; i++) ans += A[i]; printf("%lld\n", ans); continue; } if( K == 2 ) { i64d ans = 0LL; for(int i = 1; i < N; i++) ans += min(A[i], A[i - 1]); printf("%lld\n", ans); continue; } // add 1 for(int i = 0; i < N; i++) A[i] += 1LL; memset(C, 0, sizeof(C)); int l, r, m, tot, tmp; i64d ans = 0LL; for(int i = 0; i < N; i++) { if( i < K - 1 ) update((int)A[i], 1); else { update((int)A[i], 1); l = 1; r = 65536; tmp = 0; while( l <= r ) { m = (l + r) >> 1; tot = query(m); if( tot >= ((K + 1) / 2) ) { r = m - 1; tmp = m; } else l = m + 1; } ans += tmp; update((int)A[i - K + 1], -1); } } printf("%lld\n", ans - (N - K + 1LL)); } return 0; }
【F题:三角形的个数】
源自浙大月赛,考虑所有子矩形,对于每个子矩形,计算方案数,然后求和。对于每个子矩形,三角形的顶点在矩形边界的格点上,利用锐角性质,通过余弦定理得到格点间的不等式关系。
【G题:又见A+B】
模拟题,没有模出来,可以考虑再模一下。
【H题:K-数组】
排序后,统计计数即可。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<ctime> #include<cstdlib> using namespace std; const int maxN = 50000 + 2; int N, K; struct node { int val, idx; inline void in(int &_idx) { idx = _idx; scanf("%d", &val); } inline bool operator<(const node &s) const { if( val != s.val ) return val < s.val; return idx < s.idx; } }; node A[maxN]; int main() { freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); int idx = 0, nt; scanf("%d", &nt); while( (nt --) > 0 ) { scanf("%d %d", &N, &K); for(int i = 0; i < N; i++) A[i].in(i); A[0].val %= K; for(int i = 1; i < N; i++) A[i].val = (A[i - 1].val + A[i].val) % K; sort(A, A + N); long long ans = 0; int preVal = 0, totVal = 1; for(int i = 0; i < N; i++) { if( preVal == A[i].val ) { ans += (long long)totVal; totVal ++; } else { preVal = A[i].val; totVal = 1; } } cout << "Case #" << ++idx << ": " << ans << endl; } return 0; }
【I题:放苹果】
穷举法,这里放有几组输入数据的P值保留到小数点后面2位,似乎并不影响解答试题。
#include<cstdio> #include<cstring> int main() { freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); int idx = 0, nt;scanf("%d", &nt); while( (nt --) > 0 ) { int X, Y; double P; double ans = 0.0; scanf("%d %d %lf", &X, &Y, &P); for(int i = 0; i <= X; i ++) for(int j = 0; j <= Y; j++) { double cmp = 0.0; if( j ) cmp += P * j / (i + j); if( Y - j ) cmp += (1.0 - P) * (Y - j) / (X - i + Y - j); if( cmp > ans ) ans = cmp; } printf("Case #%d: %.2lf\n", ++idx, ans); } return 0; }
测试数据:
输入
30 1 1 0.5 1 1 0.0 0 0 0 0 1 0 0 1 1 10 10 0.1 100 100 0.1 100 100 0.0 100 100 0.2 100 100 0.3 100 100 0.4 100 100 0.5 100 100 0.6 100 100 0.7 100 100 0.8 100 100 0.9 56 92 0.3 14 19 0.7 20 4 0.3 12 31 0.8 56 65 0.1 65 21 0.7 13 12 0.5 16 15 0.55 10 12 0.6 32 71 0.23 31 31 0.5 31 31 0.9 17 81 0.42 61 57 0.33
输出
Case #1: 0.50 Case #2: 1.00 Case #3: 0.00 Case #4: 1.00 Case #5: 1.00 Case #6: 0.95 Case #7: 0.95 Case #8: 1.00 Case #9: 0.90 Case #10: 0.85 Case #11: 0.80 Case #12: 0.75 Case #13: 0.80 Case #14: 0.85 Case #15: 0.90 Case #16: 0.95 Case #17: 0.89 Case #18: 0.87 Case #19: 0.74 Case #20: 0.94 Case #21: 0.95 Case #22: 0.77 Case #23: 0.73 Case #24: 0.76 Case #25: 0.81 Case #26: 0.93 Case #27: 0.75 Case #28: 0.95 Case #29: 0.93 Case #30: 0.83
Thank you for your reading!
P.S. 测试数据难免会有差错,敬请指正!个人不推荐短时间内希望得到测试数据,一定程度上,不能提高个人能力。
相关文章推荐
- 2011年"新秀杯"程序设计比赛——现场决赛参考解题报告和个人总结
- 2012年"新秀杯"程序设计比赛——现场热身赛参考题解
- 2012年"新秀杯"程序设计比赛——网络预选赛参考题解
- 2012年"新秀杯"程序设计比赛——网络资格赛参考题解
- 2013年"新秀杯"程序设计网络预选赛参考题解
- 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛--n a^o7 ! 分类: 比赛 2015-06-09 17:16 14人阅读 评论(0) 收藏
- 2013年"新秀杯"程序设计网络资格赛参考题解
- 2012年第三届蓝桥杯C/C++程序设计本科B组决赛 DNA比对(编程大题)
- 2012年第三届蓝桥杯C/C++程序设计本科B组决赛 方块填数(编程大题)
- 南京林业大学“未来之星”第六届程序设计大赛(决赛)试题A 参考代码
- 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛(热身赛)
- ITAT 第九届 模拟题(江西赛区决赛) C语言程序设计 参考答案
- 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛 The Best Seat in ACM Contest 看清题目后,我是真哭了。。。。。
- 哈理工软件学院"兆方美迪"杯第六届程序设计大赛【高年级组】--决赛 Problem A:凌波微步 By Assassin
- 第十五届北京师范大学程序设计竞赛现场决赛题解&源码(A.思维,C,模拟,水,坑,E,几何,思维,K,字符串处理)
- 2012年第三届蓝桥杯C/C++程序设计本科B组决赛 DNA比对
- 南京林业大学“未来之星”第六届程序设计大赛(决赛)试题B 参考代码
- n a^o7 ! 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛 队友不在,只好划水。。。
- 哈理工软件学院"兆方美迪"杯第六届程序设计大赛【高年级组】--决赛(离官方最近的题解)
- 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛——Pixel density