本次比赛是由
XadillaX、monkeyde17、Mr.Cai、hungar以及Minary
倾情打造,大部分都是水题,考察的是基本的语法知识,解题的基本思路,以及。。。。。。看懂纯英文的题目或从输入输出推敲题意的能力
。
考虑到这次周赛的比赛结果以及童鞋们做题的情况,本次题解写的非常的简明易懂,老少咸宜,应该算得上是非常详尽了,希望本题解12届的孩纸们能够看懂无压力~
[A] Angry Leader【链接】
意思是说,一个愤怒的领导要你回答一个问题,就是给诉你一连串的数字,接着告诉你两个数字A和B,问你A、B之间的数字有多少个。这句话是重点:【just between (A, B)】,看懂这句话,这题就没问题了。考虑如下样例:1、1、2、2、3、3,给你的A = 1; B = 3; 那么答案应该是多少呢?由刚才那句话得知,答案是2而不是4。
所以程序可以这么写:
把一串数字输入数组中,再把A和B也加入到数组中,接着排序,然后用二分查找分别找到A和B的位置,设为X和Y,如果A后面的数字还是A,那么X++;B的前面还是B,那么Y--,最后输出XY中间差多少个数字即可。
Exp:
1 + 1 = 2;
5 + 5 = 0;
7 + 7 = 4;
所以90 + 19 -> 个位相加是9,十位相加是0,输出答案09而不是9;所以意思很明确,最后输出的位数是两个相加值中的大数的位数。
一个办法就是把较大数存进数组里去,倒着存,比如223 + 68,存223到num[15]中,然后从num[0]开始,每次与68%10相加,直到68最后变成0;
最后嘛,逆序输出数组即可。
这三个点是一个远的圆心,你的任务是去扩大这三个圆。
两个规矩:
①。圆形不能超过矩形的限制,以碰壁为终点。
②。下一个圆形不能改过上一个圆形。
上图为例子:
如果从左至右为1,2,3号圆形,先扩张一号圆形,碰壁了,停止,现在扩展第二个圆形,因为碰壁前就碰到上一个圆形,所以第二个圆只能这么大,第三个碰壁了,停止。然后计算三个圆扩展开来的总面积。明白题意以后来了解问题:
告诉你三个点的坐标(保证会在矩形里面),让你输出最大扩展面积,要求这个,问题就转化成谁先扩展谁后扩展的问题了。这道题的话,【Next three lines have three points】告诉了我们每次都是三个点,这意味着扩展的方案一共只有六种:123,132,213,231,312,321;依次计算这六种的面积,然后把最大的面积输出。
可以这么做:
设三个点为p1,p2,p3,半径分别为r1,r2,r3;
①。选取第i个方案;
②。扩展第一个圆p1;
③。保存这个圆的半径r1;
④。扩展第二个圆,直到碰壁或者r2>=(p2与p1的距离 - r1)结束;
⑤。扩展第三个,结束条件同④;
⑥。保存这个方案的面积area,然后回去①步骤,共重复6次。
直接上代码吧~
[A] Angry Leader【链接】
意思是说,一个愤怒的领导要你回答一个问题,就是给诉你一连串的数字,接着告诉你两个数字A和B,问你A、B之间的数字有多少个。这句话是重点:【just between (A, B)】,看懂这句话,这题就没问题了。考虑如下样例:1、1、2、2、3、3,给你的A = 1; B = 3; 那么答案应该是多少呢?由刚才那句话得知,答案是2而不是4。所以程序可以这么写:
把一串数字输入数组中,再把A和B也加入到数组中,接着排序,然后用二分查找分别找到A和B的位置,设为X和Y,如果A后面的数字还是A,那么X++;B的前面还是B,那么Y--,最后输出XY中间差多少个数字即可。
#include <set> #include <list> #include <stack> #include <queue> #include <cmath> #include <cstdio> #include <vector> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int tx, ty; int a[100010]; void find(int x, int xx, int yy, int p) { if (x == a[(xx + yy) / 2]) { if (p) tx = (xx + yy) / 2; else ty = (xx + yy) / 2; return; } if (x < a[(xx + yy) / 2]) find(x, xx, (xx + yy) / 2, p); else find(x, (xx + yy) / 2 + 1, yy, p); } int main() { int n, m, x, y; //freopen("in.in", "r", stdin); //freopen("out.out", "w", stdout); while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d%d", &x, &y); a[n] = x; a[n + 1] = y; n += 2; sort(a, a + n); if (x == a[n / 2]) tx = n / 2; else if (x < a[n / 2]) find(x, 0, n / 2, 1); else find(x, n / 2 + 1, n - 1, 1); if (y == a[n / 2]) ty = n / 2; else if (y < a[n / 2]) find(y, 0, n / 2, 0); else find(y, n / 2 + 1, n - 1, 0); if (tx == ty) { printf("0\n"); continue; } while (a[tx + 1] == x && tx < ty) tx++; while (a[ty - 1] == y && tx < ty) ty--; printf("%d\n", ty - tx - 1); } return 0; }
[B] B + A【链接】
计算A+B的值,不过有个规矩,不考虑进位的问题。Exp:
1 + 1 = 2;
5 + 5 = 0;
7 + 7 = 4;
所以90 + 19 -> 个位相加是9,十位相加是0,输出答案09而不是9;所以意思很明确,最后输出的位数是两个相加值中的大数的位数。
一个办法就是把较大数存进数组里去,倒着存,比如223 + 68,存223到num[15]中,然后从num[0]开始,每次与68%10相加,直到68最后变成0;
最后嘛,逆序输出数组即可。
#include<iostream> #include<string> #include<stdlib.h> using namespace std; int num[15]; int main() { int tmp,a,b; while(~scanf("%d%d",&a,&b)) { if(a < b){tmp = a;a = b; b = tmp;} int i = -1; while(a != 0 ) { num[++i] = a % 10; num[i] += b % 10; num[i] %= 10; a /= 10; b /= 10; } for(int j = i ; j >=0 ; j --) printf("%d",num[j]); printf("\n"); } return 0; }
[C] Come to NBUT【链接】
这道题难度比其他几道要大的多,题意是,给你一个矩形和一些点,比如4×6的矩形,和3个点;这三个点是一个远的圆心,你的任务是去扩大这三个圆。
两个规矩:
①。圆形不能超过矩形的限制,以碰壁为终点。
②。下一个圆形不能改过上一个圆形。
上图为例子:
如果从左至右为1,2,3号圆形,先扩张一号圆形,碰壁了,停止,现在扩展第二个圆形,因为碰壁前就碰到上一个圆形,所以第二个圆只能这么大,第三个碰壁了,停止。然后计算三个圆扩展开来的总面积。明白题意以后来了解问题:
告诉你三个点的坐标(保证会在矩形里面),让你输出最大扩展面积,要求这个,问题就转化成谁先扩展谁后扩展的问题了。这道题的话,【Next three lines have three points】告诉了我们每次都是三个点,这意味着扩展的方案一共只有六种:123,132,213,231,312,321;依次计算这六种的面积,然后把最大的面积输出。
可以这么做:
设三个点为p1,p2,p3,半径分别为r1,r2,r3;
①。选取第i个方案;
②。扩展第一个圆p1;
③。保存这个圆的半径r1;
④。扩展第二个圆,直到碰壁或者r2>=(p2与p1的距离 - r1)结束;
⑤。扩展第三个,结束条件同④;
⑥。保存这个方案的面积area,然后回去①步骤,共重复6次。
直接上代码吧~
#include <set> #include <list> #include <stack> #include <queue> #include <cmath> #include <cstdio> #include <vector> #include <iomanip> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define PI 3.14 double r[3][3]; double p[3][2]; double area[6]; double dis(double x1, double y1, double x2, double y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } double are(int a, int b, int c) { double ax = 0.0, nowr[3]; ax = r[a][a] * r[a][a]; nowr[0] = r[a][a]; if (r[a][b] > nowr[0]) { if (r[a][b] - nowr[0] > r[b][b]) { ax += r[b][b] * r[b][b]; nowr[1] = r[b][b]; } else { ax += (r[a][b] - nowr[0]) * (r[a][b] - nowr[0]); nowr[1] = (r[a][b] - nowr[0]); } } else nowr[1] = 0.0; if (r[a][c] > nowr[0] && r[b][c] > nowr[1]) { double xx = min(r[a][c] - nowr[0], r[b][c] - nowr[1]); if (xx < r[c][c]) { ax += xx * xx; } else { ax += r[c][c] * r[c][c]; } } return ax * PI; } int main() { double m, n; //freopen("in.in", "r", stdin); //freopen("out.out", "w", stdout); while (~scanf("%lf%lf", &m, &n)) { for (int i = 0; i < 3; i++) { scanf("%lf%lf", &p[i][0], &p[i][1]); } for (int i = 0; i < 3; i++) { for (int j = i; j < 3; j++) { if (i == j) r[i][j] = min(min(p[i][0], p[i][1]), min(n - p[i][0], m - p[i][1])); else r[i][j] = r[j][i] = dis(p[i][0], p[i][1], p[j][0], p[j][1]); } } int a = 0, b = 1, c = 2; for (int i = 0; i < 6; i++) { area[i] = are(a, b, c); if (i % 2) { int t = a; a = b; b = t; } else { int t = b; b = c; c = t; } } sort(area, area + 6); printf("%.2lf\n", area[5]); } return 0; }