【11/12】模拟赛

第一题 Ray的灰机

【题目描述】

Ray 一直在玩一个有关于灰机的小游戏,灰机是很特别的,灰机初始时有一个高度,这个高度是游戏开始你所能选择的,游戏界面中有许多圆圈,不同的圆圈有不同的高度,小Ray的灰机可以不断的穿过他们,小Ray的灰机特别再它每穿过一个圈,灰机的高度会下降,也就是说,小Ray只能要穿的圈圈只能比刚穿过的圈圈高度小,当没有圈圈穿过的时候,灰机就陨落了,小Ray不仅想知道他最多能穿多少圈圈,而且想知道穿最多圈圈的方案有多少种。因为他想让坠机的风险尽量小。

 

【输入格式】

第1行: N (1 <= N <= 5000), 表示能买股票的天数。

第2行以下: N个正整数 (可能分多行) ,第i个正整数表示第i个圈圈的高度. 这些正整数大小不会超过longint(pascal)/long(c++).

 

【输出格式】

只有一行,输出两个整数:

能够穿过圈圈的最大个数和达到这个值的方案数量

在计算解的数量的时候,如果两个解所组成的字符串相同,那么这样的两个解被认为是相同的(只能算做一个解)。
方案数不保证小于maxlongint,建议使用高精度,嘿嘿~

 

【输入样例】

6

69 64 68 64 67 62

 

【输出样例】

4 2

 

【分析】

next[i]表示i后面最近的和自己相同的数的位置。

因为要消除相同的解。所以在例如3 2 2 2 2 1中的2的数中,我们只用最后一个更新。即代码49行的if。

 

第二题 Ray的无敌城堡

【题目描述】

Ray梦想有一座座楼于世界上最美的地方——巴厘岛的梦幻城堡 幸福来的太快总叫人无法释怀 忽然有一天一张彩票不期而至,他所得到的就是真正的梦幻城堡 于是小Ray打算去学校炫耀一下,但是这之前小Ray需要知道一些东西,比如说知道城堡有多少个房间,每个房间有多大。另外,小Ray想得到一个更大的城堡,他认为城堡可以拆掉某个墙,使其变得更宽敞。你的工作就是帮小Ray做以上的准备,算出房间数不房间的大小。和使得房间变得最大的拆掉的那面墙。

城堡的平面图被划分成M*N(1 <=M,N<=50)个正方形的单位,一个这样的单位可以有0到4面墙环绕。当然城堡周围一定都是墙。

 

【输入格式】

城堡的平面图用一个由数字组成的矩阵表示,一个数字表示一个单位,矩阵有N行M列。输入不样例的图一致。

每一个单位的数字告诉我们这个单位的东西南北是否有墙存在。每个数字是由以下四个整数的某个戒某几个戒一个
都没有加起来的。

1: 在西面有墙

2: 在北面有墙

4: 在东面有墙

8: 在南面有墙

城堡内部的墙会被规定两次。

 

【输出格式】
输出如下4行:

第 1 行: 城堡的房间数目。

第 2 行: 最大的房间的大小

第 3 行: 秱除一面墙能得到的最大的房间的大小

第 4 行: 秱除哪面墙可以得到面积最大的新房间。

选择最佳的墙来推倒。有多解时选(重心)最靠西的(仍然有多解时选这些里面(重心)最靠南的)。 用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位("N"(北)或者"E"(东))。

 

【样例输入】

2 1

15 15

 

【样例输出】

2

1

2

1 1 E

 

【分析】

wall[x][y][a][b]代表(x,y)和(a,b)之间是否有墙。

第一问,floodfill一下。

第二问,同上。

后俩问,枚举。

 

第三题 Ray的扑克牌

【题目描述】

过年的时候,RAY的家里总是来很多大人来玩,大人们的情趣都很高雅,他们主要的活动就是玩神圣的存在的扑克牌,这天,正当一群人打牌打得起劲的时候,突然有人喊道:“这副牌少了几张!”,果然众人一数确实是少了几张,这时得意的Ray的妈妈说道:吼吼,不用慌,只是一副特殊的牌,我知道每一张牌的重量,只要我们称一下剩下的牌的总重量,就能知道少了哪些牌了。大家都觉得这个办法不错,于是称出剩下的牌的总重量,开始计算少了哪些牌。由于数据量比较大,过了不久,大家都算得头晕了。无奈之下,就叫来了聪明的小Ray你们看我的吧!说着小Ray于是他拿出笔记本电脑,编出了一个程序,很快就把缺少的牌找了出来。是不是很不服小Ray,如果是,也编个程序试试吧。

 

【输入格式】

第一行一个整数TotalW,表示剩下的牌的总重量。
第二行一个整数N(1<N<=100),表示这副牌有多少张。
接下来N行,每行一个整数Wi(1<=Wi<=1000),表示每一张牌的重量。

 

【输出格式】

如果无解,则输出“0”;如果有多解,则输出“-1”;否则,按照升序输出丢失的牌的编号,相邻两个数之间用一个空格隔开。

 

【样例输入】

270

4

100

110

170

200

 

【样例输出】

2 4

 

【分析】

用的背包。

f[i]代表i这个体积能否达到,two[i]代表i这个体积是否多解。

 

第四题 Ray的购物清单

【题目描述】

Ray同学喜欢去购物,但是他不想花很多钱,所以他总是挑那些打折的东西来买,现在给出他买的所有东西的一个购物清单,以及每个物品打几折,问他这次购物一共花了多少钱?

 

【输入格式】

第一行一个n(1<=n<=100)表示Ray一共买了多少个东西。
后面紧接n行,每行描述购买的一种物品:
每行2个整数ai,bi(1<=ai<=10000,1<=bi<=10)

 

【输出格式】

一行,一个实数为dog一共花了多少钱,答案保留2位小数

 

【样例输入】

2

10000 10

1 1

 

【样例输出】

10000.10

 

【分析】

模拟……

 

代码

第一题

#include <stdio.h>

#include <string.h>

#include <iostream>

#define MAXN 5010

#define MAXL 110

#define BASE 10000

using namespace std;

struct ss {

  int g[MAXL];

} num[MAXN];

int n;

int f[MAXN],a[MAXN],next[MAXN];

ss jia(ss a,ss b) {

  ss c;

  memset(c.g,0,sizeof(c.g));

  int x = 0;

  c.g[0] = max(a.g[0],b.g[0]);

  for (int i = 1;i <= c.g[0];++i) {

    x += a.g[i] + b.g[i];

    c.g[i] = x % BASE;

    x /= BASE;

  }

  if (x)

    c.g[++c.g[0]] = x;

  return c;

}

void out(ss a) {

  printf("%d",a.g[a.g[0]]);

  for (int i = a.g[0] - 1;i > 0;--i)

    printf("%d%d%d%d",a.g[i] / 1000,a.g[i] / 100 % 10,a.g[i] / 10 % 10,a.g[i] % 10);

}

int main() {

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

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

  scanf("%d",&n);

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

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

  a[++n] = -1;

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

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

      if (a[i] == a[j]) {

        next[i] = j;

        break;

      }

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

    f[i] = 1;

    num[i].g[0] = num[i].g[1] = 1;

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

      if (((!next[j]) || (next[j] > i)) && (a[j] > a[i]))

        if (f[j] + 1 > f[i]) {

          f[i] = f[j] + 1;

          num[i] = num[j];

        } else {

            if (f[j] + 1 == f[i])

              num[i] = jia(num[i],num[j]);

          }

  }

  printf("%d ",f[n] - 1);

  out(num[n]);

  return 0;

}

第二题

#include<stdio.h>

int colors;

int a[52*52];

bool wall[52][52][52][52];

int start[52*52][2];

int color[52][52];

int xx[5] = {0,0,0,1,-1};

int yy[5] = {0,1,-1,0,0};

int m,n;

int e[2],nn[2];

bool v[52][52];

bool w;

void init() {

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

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

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

      int te;

      scanf("%d",&te);

      if (te >= 8) {

        te -= 8;

        wall[i][j][i + 1][j] = 1;

        wall[i + 1][j][i][j] = 1;

      }

      if (te >= 4)  {

        te -= 4;

        wall[i][j][i][j + 1] = 1;

        wall[i][j + 1][i][j] = 1;

      }

      if (te >= 2) {

        te -= 2;

        wall[i][j][i - 1][j] = 1;

        wall[i - 1][j][i][j] = 1;

      }

      if (te >= 1) {

        wall[i][j][i][j - 1] = 1;

        wall[i][j - 1][i][j] = 1;

      }

  }

}

void fillcolor(int x,int y,int col)  {

  int tx,ty;

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

    tx = x + xx[i];

    ty = y + yy[i];

    if (tx < 1 || tx > m || ty < 1 || ty > n)

      continue;

    if (wall[x][y][tx][ty])

      continue;

    if (color[tx][ty] != 0)

      continue;

    color[tx][ty] = col;

    fillcolor(tx,ty,col);

  }

}

void findv(int x,int y,int col) {

  int tx,ty;

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

    tx = x + xx[i];

    ty = y + yy[i];

    if (tx < 1 || tx > m || ty < 1 || ty > n)

      continue;

    if (v[tx][ty])

      continue;

    if (color[tx][ty] == col) {

      ++a[col];

      v[tx][ty] = 1;

      findv(tx,ty,col);

    }

  }

}

int main() {

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

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

  init();

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

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

      if (color[i][j] == 0) {

        ++colors;

        color[i][j] = colors;

        start[colors][0] = i;

        start[colors][1] = j;

        fillcolor(i,j,colors);

      }

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

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

    v[start[i][0]][start[i][1]] = 1;

    findv(start[i][0],start[i][1],i);

  }

  int max = -1;

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

    if (a[i] > max)

      max = a[i];

  printf("%d\n",max + 1);

  max = -1;

  int ans;

  w = 1;

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

    for (int i = m;i >= 1;--i) {

      int tx,ty;

      tx = i - 1;

      ty = j;

      if (tx < 1 || tx > m || ty < 1 || ty > n)

        continue;

      if (color[tx][ty] == color[i][j])

        continue;

      if (a[color[tx][ty]] + a[color[i][j]] > max) {

        max = a[color[tx][ty]] + a[color[i][j]];

        nn[0] = i;

        nn[1] = j;

        w = 0;

      }

    }

  for (int i = m;i >= 1;--i)

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

      int tx,ty;

      tx = i;

      ty = j + 1;

      if (tx < 1 || tx > m || ty < 1 || ty > n)

        continue;

      if (color[tx][ty] == color[i][j])

        continue;

      if ((w) && (a[color[tx][ty]] + a[color[i][j]] > max)) {

        max = a[color[tx][ty]] + a[color[i][j]];

        e[0] = i;

        e[1] = j;

        w = 1;

      }

      if ((!w) && (j < nn[1] || (j == nn[1] && i > nn[0])) && (a[color[tx][ty]] + a[color[i][j]] >= max)) {

        max = a[color[tx][ty]] + a[color[i][j]];

        e[0] = i;

        e[1] = j;

        w = 1;

      }

    }

  printf("%d\n",max + 2);

  if (w)

    printf("%d %d %c\n",e[0],e[1],'E');

  else

    printf("%d %d %c\n",nn[0],nn[1],'N');

  return 0;

}

第三题

#include <stdio.h>

#include <stdlib.h>

#define MAXN 110

#define MAXV 1001

#define MAXINT 10000000

bool f[1000001],tow[1000001];

int fr[1000001],w[MAXN];

int n,v,tot,te;

int cmp(const void *a,const void *b) {

  int c = *(int *)a,d = *(int *)b;

  return c - d;

}

int main() {

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

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

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

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

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

    te += w[i];

  }

  tot = te - tot;

  f[0] = 1;

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

    for (int j = tot;j >= w[i];--j)

      if (f[j - w[i]]) {

        if (!f[j]) {

          f[j] = 1;

          fr[j] = i;

		  tow[j] = tow[j - w[i]];

        } else {

            tow[j] = 1;

          }

      }

  if (!f[tot]) {

    printf("0\n");

    return 0;

  }

  if (tow[tot]) {

    printf("-1\n");

    return 0;

  }

  n = 0;

  int ans[MAXN];

  while (tot) {

    ans[++n] = fr[tot];

    tot -= w[fr[tot]];

  }

  qsort(ans + 1,n,sizeof(int),cmp);

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

    printf("%d ",ans[i]);

  return 0;

}



第四题

#include <stdio.h>

#define MAXN 110

int x,y,n;

double ans,a,b;

int main() {

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

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

  scanf("%d",&n);

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

    scanf("%d%d",&x,&y);

    a = x;

    b = y;

    ans += a * (b / 10);

  }

  printf("%.2lf\n",ans);

  return 0;

}


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