滑铁卢ACM区域赛2006年2月题解【转载】

Waterloo ACM Programming Contest

February 25, 2006



Problem A: Educational Journey

AC:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>

int main () {
  int h, m, s;
  double x[6];
  while (1) {
    for (int i = 1; i < 6; i++) {
      if (scanf("%d:%d:%d",&h,&m,&s) != 3) return 0;
      x[i] = h*3600+m*60+s;
    }
    assert(x[1] < x[2]);
    assert(x[2] < x[3]);
    assert(x[3] < x[4]);
    assert(x[4] < x[5]);
    x[2] -= x[1];
    x[3] -= x[1];
    x[4] -= x[1];
    x[5] -= x[1];
    double A = (x[5]-x[4])/(x[5]-x[2])*(1-x[2]/x[3]);
    double B = (x[2]/x[3]-x[2]/x[4]);
    double ans = (B*x[4]+A*x[2])/(A+B)+x[1];
    char buf[100];
    sprintf(buf, "%.0f",ans); sscanf(buf,"%d",&s);
    h = s/3600; s %= 3600; m = s/60; s %= 60;
    printf("%02d:%02d:%02d\n",h,m,s);
  }
  return 0;
}


Problem B: Go

AC:

#include <stdio.h>
#include <assert.h>

#define B 1
#define W 2

int S[3];
int a[30][30], n, m;

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

void remove(int p, int x, int y) {
  S[3-p]++;
  a[x][y] = 0;
  for (int i=0;i<4;i++) 
    if (a[x+dx[i]][y+dy[i]] == 6) remove(p,x+dx[i],y+dy[i]);
}

void ff_live(int p, int x, int y) {
  a[x][y] = 5;
  for (int i=0;i<4;i++) 
    if (a[x+dx[i]][y+dy[i]] == p) ff_live(p,x+dx[i],y+dy[i]);
}
 
void undo_ff_live(int p, int x, int y) {
  a[x][y] = p;
  for (int i=0;i<4;i++) 
    if (a[x+dx[i]][y+dy[i]] == 6) undo_ff_live(p,x+dx[i],y+dy[i]);
}
 
int ff(int x, int y) {
  a[x][y]=5;
  int ret = 1;
  for (int i=0;i<4;i++) 
    if (!a[x+dx[i]][y+dy[i]]) ret += ff(x+dx[i],y+dy[i]);
  return ret;
}

int N[10];

void ngbr(int x, int y) {
  a[x][y] = 6;
  for (int i=0;i<4;i++) {
    if (a[x+dx[i]][y+dy[i]] == 0) N[0] = 1;
    if (a[x+dx[i]][y+dy[i]] == B) N[B] = 1;
    if (a[x+dx[i]][y+dy[i]] == W) N[W] = 1;
    if (a[x+dx[i]][y+dy[i]] == 5) ngbr(x+dx[i],y+dy[i]);
  }
}

int main () {
  while (1) {
    scanf("%d%d",&n,&m);
    if (!n) break;
    assert (n%2);
    for(int i=0;i<n+2;i++) 
      for(int j=0;j<n+2;j++) {
	a[i][j] = 0;
	if (!i || !j || i==n+1 || j == n+1) a[i][j] = 4;
      }
    S[1] = S[2] = 0;
    while (m--) {
      int x,y, pi;
      char pc;
      scanf(" %c(%d,%d)",&pc,&x,&y);
      pi = (pc == 'B') ? B : W;
      x += 1+n/2; y += 1+n/2;
      assert(!a[x][y]);
      a[x][y] = pi;
      for(int i=0;i<4;i++)
	if (a[x+dx[i]][y+dy[i]] == 3-pi) {
	  ff_live(3-pi,x+dx[i],y+dy[i]);
	  N[0] = 0;
	  ngbr(x+dx[i],y+dy[i]);
	  if (!N[0]) 
	    remove(3-pi,x+dx[i],y+dy[i]);
	  else 
	    undo_ff_live(3-pi,x+dx[i],y+dy[i]);
	}
      // checked earleir there were no suicides
    }
    for(int i=1;i<n+1;i++)
      for(int j=1;j<n+1;j++) 
	if (!a[i][j]) {
	  int cnt = ff(i,j);
	  N[1] = N[2] = 0;
	  ngbr(i,j);
	  if (N[1] && !N[2]) S[B]+=cnt;
	  if (!N[1] && N[2]) S[W]+=cnt;
	}
    printf("%d %d\n",S[1], S[2]);
  }
}


Problem C: Medals

AC:

#include <stdio.h>
#include <string.h>

int main () {
  while (1) {
    int n;
    scanf("%d",&n);
    if (!n) break;
    int C[100], g[100], s[100], b[100], cg = 0, cs = 0, cb = 0, Canada = 1000;
    char cn[100];
    for (int i=0;i<n;i++) {
      scanf("%s%d%d%d",cn,g+i,s+i,b+i);
      if (!strcmp(cn,"Canada")) {
	Canada = i;
	cg = g[i]; cs = s[i]; cb = b[i];
      }
    }
    double p[3];
    p[0] = 1; p[1] = 1.0/3; p[2] = 1.0/(3*3);
    for(int i = 0; i<3;i++)
      for(int j = 0; j<3; j++)
	for(int k = 0; k<3; k++) {
	  int good = 1;
	  for(int m=0; m<n; m++)
	    if (m != Canada && (cg-g[m])*p[i]+(cs-s[m])*p[j]+(cb-b[m])*p[k]<0)
	      goto B;
	  printf("Canada wins!\n");
	  goto C;
	B:;
	}
  A: printf("Canada cannot win.\n");
  C:;
  }
}


Problem D: Flipping Colors

AC:

#include <stdio.h>
#include <assert.h>

double x, y, h, v;

int doit(double llx, double lly, double urx, double ury, int col) {
  assert(llx <= x && x <= urx && lly <= y && y <= ury);
  double nx = llx+(urx-llx)*h, ny = lly+(ury-lly)*v;
  //      printf("\t\t %6.3f %6.3f\n", nx, ny);  
  if (x < nx && y < ny) 
    return doit(llx,lly,nx,ny,1-col);
  else if (x > nx && y > ny)
    return doit(nx,ny,urx,ury,1-col);    
  else if (x < nx && y > ny || x > nx && y < ny)
    return col;
  else 
    assert (0 && "too close to call");
}

int main () {

  double H, V;
  int c = 0, n;
  while (1) {
    scanf("%lf%lf%lf%lf",&H,&V,&h,&v);
    if (!H) {
      assert(!V && !h && !v);
      return 0;
    }
    printf("Case %d:\n",++c);
    scanf("%d",&n);
    while (n--) {
      scanf("%lf%lf",&x,&y);
      //      printf("\t %.10f %.10f\n", x, y);
      printf(doit(0,0,H,V,1) ? "black\n" : "white\n");
    }
  }
  
}


Problem E: Crabbles

TLE:

#include <iostream>
#include <set>
#include <string>
#include <algorithm>
#include <stdio.h>


using namespace std;

int main () {
    ios_base::sync_with_stdio(false);

  int n, h, t;
  set<string> W;
  cin >> n;
  for(int i=0;i<n;i++) {
    string s;
    cin >> s;
    sort(s.begin(),s.end());
    W.insert(s);
  }
  cin >> h;
  while(h--) {
    cin >> t;
    char C[20];
    int v[20];
    for(int i=0;i<t;i++) cin >> C[i] >> v[i];
    int maxv = 0;
    for(int b=0;b<(1<<t);b++) {
      string s;
      int cval = 0;
      for(int i=0;i<t;i++)
    if (b & (1<<i)) {
      cval += v[i];
      s += C[i];
    }
      sort(s.begin(),s.end());
      if (W.count(s) && cval > maxv) maxv = cval;
    }
    printf("%d\n",maxv);
  }
}


代码出处:http://acm.student.cs.uwaterloo.ca/~acm00/




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值