2019网易雷火笔试编程题

在网络游戏中,可见关系计算是一个非常重要的模块。有大量的功能关心一个玩家进入了另外一个玩家的视野,或者一个玩家离开了另外一个玩家的视野。
在这个题目里,我们简化了一下模型:

  1. 游戏场景是一个固定大小的二维地图,宽高分别为W和H。即坐标范围为(0, 0) ~ (W-1, H-1),且都为整数,允许不同的玩家站在同一个坐标上。
  2. 场景里有N个玩家,编号为0到N-1,初始时根据输入随机分布在各个坐标上。
  3. 玩家的视野统一为S,是一个正方形,即当玩家坐标为 (X,Y)时,他能看到范围为(X-S, Y-S)到(X+S, Y+S)这个正方形以内的其他玩家,包括这个边界坐标。
  4. 在接下来的T秒时间里,每秒这N个玩家会根据编号顺序依次产生一次移动,移动的方向由一个随机数生成器产生。
    4.1 随机数生成器生成的序列为 R(i) = (R(i-1) * 21401 + 25301) % 98765,其中序列的第0项 R0是由外部输入得到。
    4.2 第一秒第一个玩家的运动方向为R1 % 4,第一秒第二个玩家运动方向为R2 % 4,依次类推,一共产生N*T个随机数。
    4.3 假定玩家当前坐标为(X,Y),当随机出来方向为0的时候,玩家坐标变为(X-1,Y); 方向为1时,玩家坐标变为(X,Y+1); 方向为2时,玩家坐标变为(X+1,Y); 方向为3时,玩家坐标变为(X,Y-1)。
    4.4 如果玩家移动坐标将超出地图范围,则玩家停留在原地不动。
  5. 当玩家位置移动以后则可能产生跟其他玩家的可见关系的变动,比如原来A看不到B,移动以后能看到,则会产生A进入B视野和B进入A视野两个事件。反之如果原来A能看到B,移动以后看不到,则产生A离开B视野和B离开A视野两个事件。

现在,在给定的情况下,需要你帮忙计算一下,每一秒产生的进入视野事件和离开视野事件的数量。
需要注意的是,同一秒里玩家的移动也是有先后顺序的,所以可能产生在同一秒里A移动一步离开了B的视野,然后B又移动一步重新进入了A的视野。
输入描述:
每个测试输入包含1个测试用例
第一行为6个整数W,H,N,S,T,R0。含义见题目描述,范围: 0<W,H<1000, 0<N<10000, 0<S<30, 0<T<100,0<R0<98765。
接下来有N行,每行两个整数 X,Y, 依次表示这N个玩家的初始坐标,范围 0<=X<W,0<=Y<H。
输出描述:
输出T行,每行两个数字E,L,分别表示这T秒里,每秒分别产生的进入视野事件数量和离开视野事件数量。

INPUT:
5 5 3 1 2 123
1 2
2 0
3 3

OUTPUT:
2 2
2 0

乍一看这道题,满脑子都是暴力啊。。。把它想得太复杂了。时间结束后想了一下,其实题目不难。
题解:
观察题目我们发现,每个人动一下用到了随机数,也就是强制我们在线处理,这个处理过程并不复杂,4个方向可以用数组来表示
刚开始的思路是每个人动一下,和其他人的关系会发生改变,与此同时,其他人和其他人之前的关系并不会发生改变。
因此可以用N*N*t的复杂度暴力解决问题,可以过20%的case
但仔细一想我们发现每次每个人移动,带来的格子变化有多少呢?两排。

在这里插入图片描述
也就是说我们可以利用此进行计算了

希望代码可以看懂~

#include <bits/stdc++.h>
using namespace std;
struct node
{
   
	int x,y;
}p[10200];
int r[1102000];
int dx[4][2]={
   
	{
   -1,0},
	{
   0,1},
	{
   1,0},
	{
   0,-1},
};
int w,h,n,s,t;
bool valid(int x,int y){
   
	return x>=0&&x<=w-1&&y>=0&&y<=h-1;
}
int G[1024][1024];
int ask(int x,int y){
   
	if(x<0||y<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值