Topcoder SRM 573 WolfPackDivTwo

Problem Statement
    

Wolf Sothe is a member of the wolf pack called Grid Walkers. The N wolves in the pack are numbered 0 through N-1. (Wolf Sothe is the wolf number 0, but this does not matter.)  At any moment, each wolf is located at some grid point in the plane. Multiple wolves may share the same grid point. For each i, the wolf number i is initially located at (x[i],y[i]). Then there are exactly m rounds in which the wolves move. In each round, each wolf must move from its current grid point to one of the four adjacent grid points. More precisely, the wolf located at (i,j) has to move to (i+1,j), (i-1,j), (i,j+1), or (i,j-1).  The wolves have a goal: all of them have to be located at the same grid point after the m-th round. The grid point at which they all meet is not given - they can choose any grid point.  You are given the vector <int>s x and y, and the int m. Count and return the number of ways in which the wolves can reach their goal, modulo 1,000,000,007. Two ways of reaching the goal are different if in some round the same wolf moves in a different direction. (Equivalently, two ways of reaching the goal are different if there is some number of rounds x and a wolf y such that the grid point of the wolf y after x rounds of the first way differs from the grid point of the wolf y after x rounds of the second way.)


Constraints
-
x will contain between 2 and 50 elements, inclusive.
-
y will contain the same number of elements as x.
-
m will be between 1 and 50, inclusive.
-
Each element of x and y will be between 0 and 50, inclusive.
-
The points (x[i],y[i]) will be pairwise distinct.
Examples
0)


    
{3,5}
{0,0}
1
Returns: 1
There are two wolves: one at (3,0) and the other at (5,0). There will be 1 round of movement. Thus, the meeting point has to be (4,0), wolf 0 has to move by (+1,0) and wolf 1 by (-1,0). This is the only way of reaching the goal.
1)


    
{0,1}
{0,0}
1
Returns: 0
In this case the two wolves cannot be at the same grid point at the end. Note that they both have to move.
2)


    
{0,2,4}
{0,0,0}
2
Returns: 4
In this case, the meeting point has to be (2,0). Wolf 0 has to go (0,0) -> (1,0) -> (2,0). Wolf 2 has to go (4,0) -> (3,0) -> (2,0). Wolf 1 has 4 possible ways of reaching the meeting point: in the first step he can choose any direction, and in the second step he will then choose the opposite direction.
3)


    
{7,8}
{8,7}
1
Returns: 2
This time there are two possible meeting points. For each of them there is a unique way in which the wolves can reach it.
4)


    
{0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8}
{0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18}
12
Returns: 0


5)


    
{0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8}
{0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18}
31
Returns: 573748580


思路:

分别算出最终状态每条狼到每个坐标上的路径有多少条,然后把所有路径求和


代码:

/*
 * WolfPackDivTwo.cc
 *
 *  Created on: Mar 19, 2013
 *      Author: guixl
 */
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

class WolfPackDivTwo {
private:
	int ways[50][151][151];
	const static int mod_value = 1000000007;
public:
	void work(int x, int y, int turn, int m) {
		int one[151][151], two[151][151];
		memset(one, 0, sizeof(one));
		memset(two, 0, sizeof(two));
		one[x][y] = 1;
		for (int i=0; i<m; i++) {
			int *src,*tar;
			if (i%2==0) {
				src = (int*) one;
				tar = (int*) two;
			} else {
				src = (int*) two;
				tar = (int*) one;
			}
			memset(tar, 0, sizeof(one));
			for (int xx=0; xx<151; xx++)
				for (int yy=0; yy<151; yy++) if (*(src+xx*151+yy)>0) {
					int value = *(src+xx*151+yy);
					if (xx-1>=0)
						*(tar+(xx-1)*151+yy) = (*(tar+(xx-1)*151+yy) + value)%mod_value;
					if (xx+1<=150)
						*(tar+(xx+1)*151+yy) = (*(tar+(xx+1)*151+yy) + value)%mod_value;
					if (yy-1>=0)
						*(tar+xx*151+yy-1) = (*(tar+xx*151+yy-1) + value)%mod_value;
					if (yy+1<=150)
						*(tar+xx*151+yy+1) = (*(tar+xx*151+yy+1) + value)%mod_value;
				}
		}
		if (m%2==1)
			memcpy(ways[turn], two, sizeof(two));
		else
			memcpy(ways[turn], one, sizeof(one));
	}
	int calc(vector <int> x, vector <int> y, int m) {
		memset(ways, 0, sizeof(ways));
		for (int i=0; i<x.size(); i++) {
			work(x.at(i)+50, y.at(i)+50, i, m);
		}
		long long sum=0;
		for (int m=0; m<=150; m++)
			for (int n=0; n<=150; n++) {
				long long temp = 1;
				for (int i=0; i<x.size(); i++) {
					if (ways[i][m][n] <= 0) {
						temp = 0;
						break;
					} else {
						temp *= ways[i][m][n];
						if (temp>mod_value)
							temp = temp%mod_value;
					}
				}
				sum += temp;
			}
		return (int)(sum%mod_value);
	}
};

int main(int argc, char** argv) {
	int x[] = {0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8};
	int y[] = {0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18,0,2,4,6,8,10,12,14,16,18};
	vector<int> xdata(x, x+sizeof(x)/sizeof(int));
	vector<int> ydata(y, y+sizeof(y)/sizeof(int));
	WolfPackDivTwo two;
	printf("%d\n", two.calc(xdata, ydata, 31));
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值