【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;
}

posted @ 2010-11-12 14:51  Sephiroth.L.  阅读(340)  评论(0编辑  收藏  举报