【题解 Part 1】NBUT 2012 Weekly - 27th Oct for 12x

        本次比赛是由 XadillaXmonkeyde17Mr.Caihungar以及Minary 倾情打造,大部分都是水题,考察的是基本的语法知识,解题的基本思路,以及。。。。。。看懂纯英文的题目或从输入输出推敲题意的能力NBUT 2012 Weekly - 27th Oct for 12x【解题报告】 - Mr.Cai - --恢弘志士之气,不宜妄自菲薄 考虑到这次周赛的比赛结果以及童鞋们做题的情况,本次题解写的非常的简明易懂,老少咸宜,应该算得上是非常详尽了,希望本题解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中间差多少个数字即可。


#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;

NBUT 2012 Weekly - 27th Oct for 12x【解题报告 Part1】 - Mr.Cai - --恢弘志士之气,不宜妄自菲薄
最后嘛,逆序输出数组即可。
 

#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个点;

        这三个点是一个远的圆心,你的任务是去扩大这三个圆。
两个规矩:
        ①。圆形不能超过矩形的限制,以碰壁为终点。
        ②。下一个圆形不能改过上一个圆形。


NBUT 2012 Weekly - 27th Oct for 12x【解题报告 Part1】 - Mr.Cai - --恢弘志士之气,不宜妄自菲薄

上图为例子:
        如果从左至右为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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值