您的位置:首页 > 其它

uva 12559 Finding Black Circles 解题报告

2015-08-06 22:33 363 查看


I - Finding Black Circles

Time Limit:10000MS     Memory Limit:0KB     64bit
IO Format:
%lld & %llu

这道题,刘汝佳书上说了解法很多,我百度之,并没有找到任何题解,然后便一直坑之,最后终于坑出来了。

大致的思路就是,枚举圆心p,然后扫长度len(4个方向),如果该半径延伸到的距离,4周(包括它)在mp里面都是1

那么说明可能存在以p为圆心,len为半径的圆,然后进行dfs,按照圆的构造方法(别问我怎么知道构造圆的概率,试出来的,记住就好)进行dfs,虚拟构造一个圆,并且在构造的同时,要判断相应位置是否为1,如果为1,那么这里(虚拟看成圆的周长一部分)cnt加1

接下来,用跑出来的cnt 和 计算得到的构造出一个圆该有的周长作除比较。判断差距小于等于0.2即可(也别问我,反正0.01wa,0.1wa,0.2就过了)

具体见代码

//

//  Created by Running Photon on 2015-08-04

//  Copyright (c) 2015 Running Photon. All rights reserved.

//

#include <algorithm>

#include <cctype>

#include <cmath>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <iomanip>

#include <iostream>

#include <map>

#include <queue>

#include <string>

#include <sstream>

#include <set>

#include <vector>

#include <stack>

#define ALL(x) x.begin(), x.end()

#define INS(x) inserter(x, x,begin())

#define ll long long

#define CLR(x) memset(x, 0, sizeof x)

using namespace std;

const int inf = 0x3f3f3f3f;

const int MOD = 1e9 + 7;

const int maxn = 1e4 + 10;

const double eps = 1e-9;

int t, n, m, top, cnt;

struct pnt {

 int r, x, y;

 bool operator < (const pnt & rhs) const {

  if(r == rhs.r) {

   if(y == rhs.y) return x < rhs.x;

   return y < rhs.y;

  }

  return r < rhs.r;

 }

}a[maxn];

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

int mp[200][200];

int vis[200][200];

bool check(int x, int y) {

 return x >= 0 && x < n && y >= 0 && y < m;

}

void dfs(int x, int y, int len, int X, int Y) {

 if(mp[x][y]) cnt++;

 vis[x][y] = (X * n + Y) * m + len;

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

  int nx = x + dir[i][0];

  int ny = y + dir[i][1];

  if(!check(nx, ny) || vis[nx][ny] == (X * n + Y) * m + len) continue;

  double D = sqrt((double)(nx-X)*(nx-X) + (double)(ny-Y)*(ny-Y));

  if(abs(D - (double) len) <= 0.70) {

   dfs(nx, ny, len, X, Y);

  }

 }

}

bool checkn(int x, int y) {

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

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

   int nx = x + dir[i][0];

   int ny = y + dir[i][1];

   if(check(nx, ny) && mp[nx][ny]) return true;

  }

 }

 return false;

}

void sol(int x, int y) {

 for(int len = 5; len <= min(min(x, y), min(n-x, m-y)); len++) {

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

   int nx = len * dir[i][0] + x;

   int ny = len * dir[i][1] + y;

   if(checkn(nx, ny) && vis[nx][ny] != (x * n + y) * m + len) {

    cnt = 0;

    if(vis[nx][ny] != (x * n + y) * m + len) {

     dfs(nx, ny, len, x, y);

    }

    double tmp = cnt * 1.0 / (8.0 * len);

    if(abs(tmp - 1) <= 0.2) {

//

//      for(int ii = 0; ii < n; ii++) {

//       for(int jj = 0; jj < m; jj++) {

//        if(vis[ii][jj] == (x * n + y) * m + len && mp[ii][jj]) printf("1");

//        else printf("0");

//       }

//       printf("\n");

//      }

//      printf("cnt = %d   tmp = %d\n", cnt, 8 * len);

     a[top].r = len;

     a[top].x = x;

     a[top++].y = y;

    }

   }

  }

 }

}

int main() {

#ifdef LOCAL

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

// freopen("out.txt","w",stdout);

#endif

 ios_base::sync_with_stdio(0);

 scanf("%d", &t);

 int cas = 0;

 while(t--) {

  CLR(mp); CLR(vis);

  top = 0;

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

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

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

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

  for(int i = 5; i < n-5; i++) {

   for(int j = 5; j < m-5; j++) {

     if(top < 5)

      sol(i, j);

   }

  }

  sort(a, a + top);

  printf("Case %d: %d", ++cas, top);

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

   printf(" (%d,%d,%d)", a[i].r, a[i].y, a[i].x);

  }

  printf("\n");

 }

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: