【11/1】模拟赛

老规矩,程序放在最后。


第一题 油滴扩展

【题目描述】

一个长方形的盒子。最多有N个相异的点。每个点可以放上一个油滴,油滴会扩展,知道接触到其他油滴或者盒子边缘。请确定一种放置顺序,使得油滴占据的总面积最大。


【输入格式】

第一行一个整数N。

第二行为长方形边框的一个顶点和其对角顶点的坐标x,y,x’,y’。

接下来的N行,每行两个整数xi,yi,表示盒子里的点。

保证所有的整数都在[-1000,1000]范围。

 

【输出格式】

一行一个整数,长方形盒子剩余的最小空间(结果四舍五入)。


【样例输入】

2

0 0 10 10

3 3

7 7

 

【样例输出】

50

 

【分析】

递归搜索。

 

第二题 数列

直接传送门。

http://www.cnblogs.com/sephirothlee/archive/2010/10/08/1846073.html

 

第三题 SOFTWARE

再次传送门。

http://www.cnblogs.com/sephirothlee/archive/2010/10/09/1846498.html

 

第四题 黑匣子

【题目描述】

black box是一种原始的数据库。他可以储存一个整数数组,还有一个特别的变量i。最开始的时候black box是空的,而i等于0。这个black box要处理一串命令。

命令只有两种:

ADD(X):把X元素放进black box中;

GET:i加1,然后输出black box中第i小的数。

现在用两个整数数组来表示命令串:

1.A(1),A(2)……A(M):一串将要被放进black box中的元素。每个书都是绝对值不超过2000000000的整数,M<=200000。

2.U(1),U(2)……U(N):表示第U(J)个元素被放入black box中后就出现一个GET命令。输入数据不用判错。

 

【输入格式】

第一行:两个整数,M,N。

第二行:M个整数,表示A(1)……A(M)。

第三行:N个整数,表示U(1)……U(N)。

 

【输出格式】

输出根据命令串所得出的输出串,一个数字一行。

 

【输入样例】

7 4

3 1 –4 2 8 –1000 2

1 2 6 6

 

【输出样例】

3

3

1

2

 

【数据范围】

对于30%的数据,M<=10000;

对于50%的数据,M<=100000;

对于100%的数据,M<=200000。

 

【分析】

一个treap解决。


代码

第一题

#include <stdio.h>

#include <math.h>

#define MAXN 10

#define pi 3.1415926535

struct ss {

  int x,y;

  double r;

  bool v;

} a[MAXN];

int n;

double maxs;

int xx[2],yy[2];

double abs(double x) {

  if (x < 0)

    x = 0 - x;

  return x;

}

double dis(double x1,double y1,double x2,double y2) {

  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));

}

int si(double x) {

  int te = (int) x;

  if (te + 0.5 > x)

    return te;

  else

    return te + 1;

}

void find(int x) {

  if (x > n) {

    double tem = 0;

    for (int i = 1;i <= n;++i)

      tem += pi * a[i].r * a[i].r;

    if (tem > maxs)

      maxs = tem;

    return;

  }

  for (int i = 1;i <= n;++i)

    if (!a[i].v) {

      double temr = 1000000010;

      for (int j = 1;j <= n;++j)

        if (a[j].v) {

          double temp = dis(a[j].x,a[j].y,a[i].x,a[i].y) - a[j].r;

          if (temp < temr)

            temr = temp;

        }

      for (int j = 0;j < 2;++j) {

        if (abs(xx[j] - a[i].x) < temr)

          temr = abs(xx[j] - a[i].x);

        if (abs(yy[j] - a[i].y) < temr)

          temr = abs(yy[j] - a[i].y);

      }

      if (temr < 0)

        temr = 0;

      a[i].v = 1;

      a[i].r = temr;

      find(x + 1);

      a[i].v = 0;

    }

}

int main() {

  freopen("box.in","r",stdin);

  freopen("box.out","w",stdout);

  scanf("%d",&n);

  for (int i = 0;i < 2;++i)

    scanf("%d%d",&xx[i],&yy[i]);

  for (int i = 1;i <= n;++i)

    scanf("%d%d",&a[i].x,&a[i].y);

  find(1);

  double ans = abs(xx[0] - xx[1]) * abs(yy[0] - yy[1]);

  ans = ans - si(maxs);

  printf("%d\n",(int)ans);

  return 0;

}



 

第二题

#include <stdio.h>

#include <iostream>

#define MAXN 1010

using namespace std;

int f[MAXN][MAXN][2],a[MAXN],ans,n;

bool have[MAXN][MAXN];

void find(int x,int y) {

  if (have[x][y]) return;

  if ((y > x) || (y < 0) || (x < 0)) return;

  have[x][y] = 1;

  find(x - 1,y - 1);

  find(x - 1,y);

  if (x - 1 < 0) return;

  f[x][y][0] = f[x - 1][y][0];

  if ((y - 1 >= 0) && (f[x - 1][y][1] > f[x][y][0]))

    f[x][y][0] = f[x - 1][y][1];

  bool t = (a[x] == (x - y));

  if (t)

    ++f[x][y][0];

  if (y - 1 >= 0)

    f[x][y][1] = max(f[x - 1][y - 1][0],f[x - 1][y - 1][1]);

}

int main() {

  freopen("sequence.in","r",stdin);

  freopen("sequence.out","w",stdout);

  scanf("%d",&n);

  for (int i = 1;i <= n;++i)

    scanf("%d",&a[i]);

  for (int i = 0;i <= n;++i)

    find(n,i);

  for (int i = 0;i <= n;++i) {

    if (f[n][i][0] > ans)

      ans = f[n][i][0];

    if (f[n][i][1] > ans)

      ans = f[n][i][1];

  }

  printf("%d\n",ans);

  return 0;

}



 

第三题

#include <stdio.h>

#include <string.h>

#include <iostream>

#define MAXN 110

using namespace std;

int w[MAXN][2],f[MAXN][MAXN];

int n,m,max_time,l,r,mid;

bool check(int mid) {

  memset(f,-1,sizeof(f));

  f[0][0] = 0;

  for (int i = 1;i <= n;++i)

    for (int j = 0;j <= m;++j) {

      if (f[i - 1][j] < 0) continue;

      for (int k = 0;(j + k <= m) && (mid >= w[i][0] * k);++k)

        if (f[i][j + k] < f[i - 1][j] + (mid - w[i][0] * k) / w[i][1])

          f[i][j + k] = f[i - 1][j] + (mid - w[i][0] * k) / w[i][1];

    }

  return f[n][m] >= m;

}

int main() {

  freopen("software.in","r",stdin);

  freopen("software.out","w",stdout);

  scanf("%d%d",&n,&m);

  for (int i = 1;i <= n;++i) {

    scanf("%d%d",&w[i][0],&w[i][1]);

    if (w[i][0] > max_time)

      max_time = w[i][0];

    if (w[i][1] > max_time)

      max_time = w[i][1];

  }

  r = max_time * m;

  l = 1;

  while (l <= r) {

    mid = (l + r) / 2;

    if (check(mid))

      r = mid - 1;

    else

      l = mid + 1;

  }

  printf("%d\n",l);

  return 0;

}



 

第四题

#include<stdio.h>

#include<stdlib.h>

#define mmm 1000000

#define MAXN 200010

struct ss

{

       int left,right,key,data,count,size;

} t[mmm+1];

int n,m,x,y,tot,tott,root;

int a[MAXN],u[MAXN];



void modify(int x)

{

     t[x].size=t[t[x].left].size+t[x].count+t[t[x].right].size;

}



void leftrotate(int *x)

{

     int te=t[*x].left;

     t[*x].left=t[te].right;

     t[te].right=*x;

     modify(*x); *x=te; modify(*x);

}



void rightrotate(int *x)

{

     int te=t[*x].right;

     t[*x].right=t[te].left;

     t[te].left=*x;

     modify(*x); *x=te; modify(*x);

}



void insert(int *x,int y)

{

     if (*x==0)

     {

               *x=++tot;

               t[*x].left=0; t[*x].right=0;

               t[*x].size=1; t[*x].count=1;

               t[*x].key=rand()%mmm; t[*x].data=y;

     }

     else

     {

         if (y==t[*x].data) ++t[*x].count;

         else

         if (y<t[*x].data)

         {

                          insert(&t[*x].left,y);

                          if (t[t[*x].left].key<t[*x].key)

                             leftrotate(x);

         }

         else

         {

             insert(&t[*x].right,y);

             if (t[t[*x].right].key<t[*x].key)

                rightrotate(x);

         }

         modify(*x);

     }

}

int findkth(int x,int y)

{

    if (y<=t[t[x].left].size) return findkth(t[x].left,y); else

    if (y<=t[t[x].left].size+t[x].count) return t[x].data; else

    return findkth(t[x].right,y-t[t[x].left].size-t[x].count);

}



int main()

{

  freopen("blackbox.in","r",stdin);

  freopen("blackbox.out","w",stdout);

  scanf("%d%d",&m,&n);

  srand(n);

  for (int i = 1;i <= m;++i)

    scanf("%d",&a[i]);

  for (int i = 1;i <= n;++i)

    scanf("%d",&u[i]);

  int now = 1,get = 0,ans;

  for (int i = 1;i <= m;++i) {

    insert(&root,a[i]);

    while (i == u[now]) {

      ++now;

      ++get;

      ans = findkth(root,get);

      printf("%d\n",ans);

    }

  }

  return 0;

}



 

 

 

你可能感兴趣的:(模拟)