Time Limited Exceeded => Bit operations (repeated operations on many)

http://codeforces.com/problemset/problem/97/D

Robot in Basement
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The Professor has lost his home robot yet again. After some thinking Professor understood that he had left the robot in the basement.

The basement in Professor's house is represented by a rectangle n × m, split into 1 × 1 squares. Some squares are walls which are impassable; other squares are passable. You can get from any passable square to any other passable square moving through edge-adjacent passable squares. One passable square is the exit from the basement. The robot is placed exactly in one passable square. Also the robot may be placed in the exit square.

Professor is scared of going to the dark basement looking for the robot at night. However, he has a basement plan and the robot's remote control. Using the remote, Professor can send signals to the robot to shift one square left, right, up or down. When the robot receives a signal, it moves in the required direction if the robot's neighboring square in the given direction is passable. Otherwise, the robot stays idle.

Professor wrote a sequence of k commands on a piece of paper. He thinks that the sequence can lead the robot out of the basement, wherever it's initial position might be. Professor programmed another robot to press the required buttons on the remote according to the notes on the piece of paper. Professor was just about to run the program and go to bed, when he had an epiphany.

Executing each command takes some energy and Professor doesn't want to get huge electricity bill at the end of the month. That's why he wants to find in the sequence he has written out the minimal possible prefix that would guarantee to lead the robot out to the exit after the prefix is fulfilled. And that's the problem Professor challenges you with at this late hour.


Input

The first line contains three integers nm and k (3 ≤ n, m ≤ 1501 ≤ k ≤ 105). Next n lines contain m characters each — that is the Professor's basement's description: "#" stands for a wall, "." stands for a passable square and "E" stands for the exit from the basement (this square also is passable). It is possible to get from each passable square to the exit, all squares located by the n × m rectangle's perimeter are the walls. Exactly one square is the exit from the basement. The last line contains k characters, the description of the sequence of commands that Professor has written out on a piece of paper. "L", "R", "U", "D" stand for commands left, right, up and down correspondingly.


Output

Print in the output file the length of the smallest possible prefix that will lead the robot to the exit square. In other words, wherever the robot had been positioned initially, it should be positioned in the exit square after all the commands from the prefix are fulfilled (during doing commands the robot can come and leave the exit square, but only the last position of the robot is interesting for us). If Professor is mistaken and no prefix (including the whole sequence) can bring the robot to the exit, print "-1" (without the quotes). If there is the only passable square and it is the exit, print "0" (without the quotes).


Sample test(s)
input
5 5 7
#####
#...#
#...#
#E..#
#####
UULLDDR
output
6
input
5 5 7
#####
#.#.#
#...#
#E..#
#####
UULLDDR
output
-1
input
5 3 2
###
#.#
#.#
#E#
###
DD
output
2








ACRush

#include <string>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <functional>
#include <utility>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
 
using namespace std;
 
typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (1<<(X))
#define twoL(X) (((int64)(1))<<(X))
#define contain(S,X) ((S&two(X))>0)
#define containL(S,X) ((S&twoL(X))>0)
typedef pair<int,int> ipair;
int countbit(int n) {return (n==0)?0:(1+countbit(n&(n-1)));}
int lowbit(int n) {return (n^(n-1))&n;}
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> T sqr(T x) {return x*x;}
template<class T> void checkmin(T &a,T b) {if (b<a) a=b;}
template<class T> void checkmax(T &a,T b) {if (b>a) a=b;}
#define SIZE(X) ((int)((X).size()))
#define LENGTH(X) ((int)((X).length()))
#define MP(A,B) make_pair(A,B)
typedef unsigned int uint;

const int maxk=100000+5;

int n,m,k,dstx,dsty;
uint mask[160][5],state[160][5];
uint blockL[160][5],blockR[160][5],blockU[160][5],blockD[160][5];
char g[160][160];
char cmd[maxk];

bool ck()
{
	for (int i=0;i<n;i++) 
		if (i!=dstx)
		{
			for (int j=0;j<5;j++) if (state[i][j]) return false;
		}
		else
		{
			for (int j=0;j<5;j++) if (j!=(dsty>>5) && state[i][j]) return false;
			if (state[i][dsty>>5]!=(1u<<(dsty&31))) return false;
		}
	return true;
}
int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	memset(mask,0,sizeof(mask));
	scanf("%d%d%d",&n,&m,&k);
	memset(blockL,0,sizeof(blockL));
	memset(blockR,0,sizeof(blockR));
	memset(blockU,0,sizeof(blockU));
	memset(blockD,0,sizeof(blockD));
	for (int i=0;i<n;i++)
	{
		scanf("%s",g[i]);
		for (int j=0;j<m;j++)
			if (g[i][j]!='#')
			{
				mask[i][j>>5]|=(1u<<(j&31));
				if (g[i][j]=='E') dstx=i,dsty=j;
			}
	}
	for (int x=0;x<n;x++) for (int y=0;y<m;y++) if (g[x][y]!='#')
	{
		if (g[x][y-1]=='#') blockL[x][y>>5]|=(1u<<(y&31));
		if (g[x][y+1]=='#') blockR[x][y>>5]|=(1u<<(y&31));
		if (g[x-1][y]=='#') blockU[x][y>>5]|=(1u<<(y&31));
		if (g[x+1][y]=='#') blockD[x][y>>5]|=(1u<<(y&31));
	}
	scanf("%s",cmd);
	memcpy(state,mask,sizeof(state));
	if (ck()) 
	{
		printf("0\n");
		return 0;
	}
	for (int step=0;step<k;step++)
	{
		char key=cmd[step];
		if (key=='L')
		{
			uint last=0;
			for (int x=0;x<n;x++) for (int i=4;i>=0;i--)
			{
				uint next=state[x][i]&1;
				state[x][i]=(state[x][i]&blockL[x][i])|(state[x][i]>>1);
				if (last) state[x][i]|=(1u<<31);
				last=next;
			}
		}
		else if (key=='R')
		{
			uint last=0;
			for (int x=0;x<n;x++) for (int i=0;i<5;i++)
			{
				uint next=state[x][i]>>31;
				state[x][i]=(state[x][i]&blockR[x][i])|(state[x][i]<<1)|last;
				last=next;
			}
		}
		else if (key=='U')
		{
			for (int x=0;x<n;x++) 
			{
				for (int i=0;i<5;i++) state[x][i]&=blockU[x][i];
				if (x+1<n) for (int i=0;i<5;i++) state[x][i]|=state[x+1][i];
			}
		}
		else
		{
			for (int x=n-1;x>=0;x--) 
			{
				for (int i=0;i<5;i++) state[x][i]&=blockD[x][i];
				if (x-1>=0) for (int i=0;i<5;i++) state[x][i]|=state[x-1][i];
			}
		}
		for (int x=0;x<n;x++) for (int i=0;i<5;i++) state[x][i]&=mask[x][i];
/*
		for (int x=0;x<n;x++) 
		{
			for (int y=0;y<m;y++) if (state[x][y>>5]&(1u<<(y&31)))
				printf("1");
			else
				printf("0");
			printf("\n");
		}
		printf("\n");
*/
		if (ck()) 
		{
			printf("%d\n",step+1);
			return 0;
		}
	}
	printf("-1\n");
	return 0;
}




Another solution using STL bitset

#include<cstdio>
#include<bitset>
#include<algorithm>
using namespace std;
int n,m,k;char s[100010];
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    bitset<22500> a,b,e,c;
    for(int i=0;i<n;i++)
    {
        scanf("%s",s);
        for(int j=0;j<m;j++)
            (s[j]=='#'?b:a).set(i*m+j),
            (s[j]=='E'?e.set(i*m+j):0);
    }
    scanf("%s",s);c=a;
    for(int i=0;i<k;i++)
    {
        if(c==e){printf("%d\n",i);return 0;}
        if(s[i]=='U')c=((c>>m)&a)|(c&(b<<m));else
        if(s[i]=='L')c=((c>>1)&a)|(c&(b<<1));else
        if(s[i]=='D')c=((c<<m)&a)|(c&(b>>m));else
        if(s[i]=='R')c=((c<<1)&a)|(c&(b>>1));
    }
    printf("%d\n",c==e?k:-1);
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值