【11/11】模拟赛

官方的链接:http://www.byvoid.com/blog/byvoid-wow-stage-3/

本博客不再给出题目。

第一题 彩色穿孔卡片

用的O(N^2)的算法。类似USACO的浮水法。

 

第二题 艾萨拉的激流

f[i][j] = max{

f[i – 1][j – 1]

f[i – 1][j]

f[i – 1][j + 1]

} + a[i][j]

 

第三题 阿鲁高的阴谋

设f[i][j]是第i天过去后,存下了j的燃料。设l是第i天骗的燃料数。k是上一天剩下的燃料数。

k + l = n[i] + j,推出k = n[i] + j – l。

f[i][j] = min{f[i][j],f[i – 1][k] + l * b[i] + j * w}。

 

第四题 潜入辛迪加

多状态的宽搜。用state表示所有钥匙的状态。第i个钥匙对应的位置为1 << (i – 1)。

v[state][i][j]代表state状态下,(i,j)这个位置是否到过。

 

代码

第一题

#include <stdio.h>

#include <iostream>

#define MAXN 200001

using namespace std;

struct ss {

  int l,r;

} a[MAXN];

bool have[MAXN];

int ans,n;

void flo(int l,int r,int x,int co) {

  if (l >= r)

    return;

  if (have[co])

    return;

  if (x > n) {

    have[co] = 1;

    ++ans;

    return;

  }

  if (have[co])

    return;

  if (a[x].l >= l)

    flo(l,min(a[x].l,r),x + 1,co);

  if (a[x].r <= r)

    flo(max(a[x].r,l),r,x + 1,co);

}

int main() {

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

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

  scanf("%d",&n);

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

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

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

    flo(a[i].l,a[i].r,i + 1,i);

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

  return 0;

}



第二题

#include <stdio.h>

#include <string.h>

#define MAXN 1010

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

int n,m,ans,now,last;

int main() {

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

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

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

  now = 1;

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

    last = now;

    now ^= 1;

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

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

    memset(f[now],255,sizeof(f[now]));

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

      if (a[j] != -1) {

        if ((j - 1 > 0) && (f[last][j - 1] != -1) && (f[last][j - 1] + a[j] > f[now][j]))

          f[now][j] = f[last][j - 1] + a[j];

        if ((f[last][j] != -1) && (f[last][j] + a[j] > f[now][j]))

          f[now][j] = f[last][j] + a[j];

        if ((j + 1 <= m) && (f[last][j + 1] != -1) && (f[last][j + 1] + a[j] > f[now][j]))

          f[now][j] = f[last][j + 1] + a[j];

      }

  }

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

    if (f[now][j] > ans)

      ans = f[now][j];

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

  return 0;

}



第三题

#include <stdio.h>

#define MAXT 1010

#define MAXINT 10000000

int b[MAXT],n[MAXT];

int t,v,a,w,x,y;

int f[MAXT][110],d[MAXT][110],ans[MAXT];

int main() {

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

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

  scanf("%d%d%d%d",&t,&v,&a,&w);

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

    for (int j = 0;j <= v;++j)

      f[i][j] = MAXINT;

  f[0][0] = 0;

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

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

    for (int j = 0;j <= v;++j)

      for (int l = 0;l <= a;++l) {

        int k = n[i] + j - l;

        if ((k >= 0) && (k <= v))

          if (f[i - 1][k] + j * w + b[i] * l < f[i][j]) {

            f[i][j] = f[i - 1][k] + j * w + b[i] * l;

            d[i][j] = l;

          }

      }

  }

  int mi = MAXINT;

  y = 0;

  mi = f[t][0];

  for (int i = t;i > 0;--i) {

    ans[i] = d[i][y];

    y = n[i] + y - d[i][y];

  }

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

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

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

  return 0;

}



第四题

#include <stdio.h>

#include <iostream>

#define MAXN 51

#define MAXL 10000000

using namespace std;

struct ss {

  int x,y,dis,state;

} q[MAXL];

int n,m,tex,tey,x,y,state,dis,l,r;

int a[MAXN][MAXN];

bool v[65527][MAXN][MAXN];

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

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

void add(int x,int y,int di,int state) {

  if ((x == n) && (y == n)) {

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

    exit(0);

  }

  if (a[x][y] < 0)

    return;

  if (a[x][y] == 0) {

    r = (r + 1) % MAXL;

    q[r].x = x;

    q[r].y = y;

    q[r].dis = di + 1;

    q[r].state = state;

    v[state][x][y] = 1;

    return;

  }

  if (a[x][y] <= m) {

    state |= (1 << (a[x][y] - 1));

    r = (r + 1) % MAXL;

    q[r].x = x;

    q[r].y = y;

    q[r].dis = di + 1;

    q[r].state = state;

    v[state][x][y] = 1;

    return;

  }

  if ((state >> (a[x][y] - m - 1)) & 1) {

    r = (r + 1) % MAXL;

    q[r].x = x;

    q[r].y = y;

    q[r].dis = di + 1;

    q[r].state = state;

    v[state][x][y] = 1;

    return;

  }

}

bool inmap(int x,int y) {

  return (x > 0) && (x <= n) && (y > 0) && (y <= n);

}

int main() {

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

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

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

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

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

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

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

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

      if (a[i][j] == -2)

        for (int k = 0;k < 4;++k) {

          tex = i + xx[k];

          tey = j + yy[k];

          if (inmap(tex,tey) && (a[tex][tey] != -2))

            a[tex][tey] = -1;

        }

  /*

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

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

      printf("%d ",a[i][j]);

    printf("\n");

  }

  */

  q[0].x = q[0].y = 1;

  while (l <= r) {

    x = q[l].x;

    y = q[l].y;

    dis = q[l].dis;

    state = q[l].state;

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

      tex = x + xx[i];

      tey = y + yy[i];

      if (inmap(tex,tey) && (!v[state][tex][tey]))

        add(tex,tey,dis,state);

    }

    l = (l + 1) % MAXL;

  }

}




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