[BFS 剪枝] BZOJ 2954 [Poi2002]超级马

直接以(0,0)广搜,判断是否能到(0,1)(0,-1)(1,0)(-1,0)但直接这样做复杂度过高,需要利用以下剪枝。

1. 限制在(-100..100,-100..100)内移动

2. 移动到一个点(x,y)时,判断(-x,-y)周围是否已到达

3. 一旦判断成功,立即退出


第一点剪枝的正确性本人尚不明

第二点剪枝还是很妙的 不过没写


几年前做的题 连代码是不是自己写的都不记得了 如果发现雷同代码 请随意鄙视我


#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
const int sumpoints = 40401;
int T, n;
int dx[101], dy[101];
bool vis[201][201];

inline int gcd(int a,int b){
  if (a<b) return gcd(b,a);
  if (b==0) return a;
  return gcd(b,a%b);
}

struct pnt {
  int x, y;
  pnt(int x = 100, int y = 100) :x(x), y(y) {}
};
bool bfs() {
  queue <pnt> q;
  q.push(pnt());
  vis[100][100] = true;
  pnt u;
  while(!q.empty()) {
    u = q.front();
    q.pop();
    for(int i = 1; i <= n; ++i) {
      u.x += dx[i]; u.y += dy[i];
      if(u.x>=0 && u.x<=200 && u.y>=0 && u.y<=200)
	if(!vis[u.x][u.y]) {
	  q.push(u);
	  vis[u.x][u.y] = true;
	  if(vis[100][99] && vis[100][101] && vis[99][100] && vis[101][100])
	    return true;
	}
      u.x -= dx[i]; u.y -= dy[i];
    }
  }
  if(vis[100][99] && vis[100][101] && vis[99][100] && vis[101][100]) return true;
  else return false;
}
int main() {
  freopen("t.in", "r", stdin);
  freopen("t.out", "w", stdout);
  scanf("%d", &T);
  while(T--) {
    memset(dx, 0, sizeof(dx));
    memset(dy, 0, sizeof(dy));
    memset(vis, false, sizeof(vis));
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
      scanf("%d%d", &dx[i], &dy[i]);
    if (n>=2){
      int G=gcd(abs(dx[1]),abs(dx[2]));
      for (int i=3;i<=n;i++)
	G=gcd(G,abs(dx[i]));
      if (G>1) { puts("NIE"); continue; }
      G=gcd(abs(dy[1]),abs(dy[2]));
      for (int i=3;i<=n;i++)
	G=gcd(G,abs(dy[i]));
      if (G>1) { puts("NIE"); continue; }
    }
    if(bfs()) puts("TAK");
    else puts("NIE");
  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值