Codeforces243C-Colorado Potato Beetle(离散化+bfs)

Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. The field is divided into square garden beds, each bed takes up one square meter.

Old McDonald knows that the Colorado potato beetle is about to invade his farm and can destroy the entire harvest. To fight the insects, Old McDonald wants to spray some beds with insecticides.

So Old McDonald went to the field, stood at the center of the central field bed and sprayed this bed with insecticides. Now he‘s going to make a series of movements and spray a few more beds. During each movement Old McDonald moves left, right, up or down the field some integer number of meters. As Old McDonald moves, he sprays all the beds he steps on. In other words, the beds that have any intersection at all with Old McDonald‘s trajectory, are sprayed with insecticides.

When Old McDonald finished spraying, he wrote out all his movements on a piece of paper. Now he wants to know how many beds won‘t be infected after the invasion of the Colorado beetles.

It is known that the invasion of the Colorado beetles goes as follows. First some bed on the field border gets infected. Than any bed that hasn‘t been infected, hasn‘t been sprayed with insecticides and has a common side with an infected bed, gets infected as well. Help Old McDonald and determine the number of beds that won‘t be infected by the Colorado potato beetle.

Input

The first line contains an integer n (1 ≤ n ≤ 1000) — the number of Old McDonald‘s movements.

Next n lines contain the description of Old McDonald‘s movements. The i-th of these lines describes the i-th movement. Each movement is given in the format "dixi", where di is the character that determines the direction of the movement ("L", "R", "U" or "D" for directions "left", "right", "up" and "down", correspondingly), and xi (1 ≤ xi ≤ 106) is an integer that determines the number of meters in the movement.

Output

Print a single integer — the number of beds that won‘t be infected by the Colorado potato beetle.

Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64dspecifier.

Sample Input

Input

5 R 8 U 9 L 9 D 8 L 2

Output

101

Input

7 R 10 D 2 L 7 U 9 D 2 R 3 D 10

Output

52

题意:有一个非常大的田地(你当它是无穷大的),每一格大小是1m*1m,主人公要喷杀虫剂,他从起点开始,可以朝U(上),D(下),L(左),R(右)四个方向走一段距离,则这段路上的格子都被喷了杀虫剂,给出N次操作,每次输入一个字符和数字,分别代表方向和路程。害虫入侵田地的方式是从外围入侵,如果某个相邻的格子没有被喷杀虫剂则可以蔓延。最后要求出剩下没被入侵的总面积。

解析:田地太大,面积太大,直接搜是不可能的,但是N最大只有1000,那么可以考虑把x坐标y坐标离散化,点最多也就上千,这里有一个技巧,就是离散化后的点扩大两倍,为了后面方便bfs,所以我把最外围扩了一圈,那么离散的坐标就是1,3,5.....2*k+1。 0和2*k+2是外围。我把整个图压缩成了一维,比如(x,y)对应的下标就是x*列宽+y,接下来就是bfs,先把走过的地方全部标记为1,其他地方标记为-1,此时我只需要把(0,0)加入队列搜即可(你可以仔细想一下为什么),把能够走的地方全部标记为0。但是要注意一点,因为我是扩大了两倍,如果当前搜的方向是上或下,且这个点的y坐标是偶数(不是边界),需要判断一下离散化的左右两个数的差值是否为1,是的话是不能走的(被堵死了),因为这个点本就是虚拟的点。如果当前搜的方向是左或右,x坐标是偶数(不是边界)同理。最后就是计算总面积,如果这个点不是标记为0(不能被害虫入侵),则判断它的x,y坐标的奇偶性,x,y同时为奇数则加1,x为偶数,则加x轴方向的距离-1,y为偶数,则加y轴方向的距离-1,都是偶数则加两个方向的距离-1的乘积。(注意会爆int)代码#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<sstream>#include<algorithm>#include<utility>#include<vector>#include<set>#include<map>#include<queue>#include<cmath>#include<iterator>#include<stack>using namespace std;typedef __int64 LL;const int INF=1e9+7;const double eps=1e-7;const int maxn=2002;int M,wx[maxn],wy[maxn];int tempx[maxn],tempy[maxn],row,col;int dx[]={-1,0,1,0},dy[]={0,-1,0,1};int maze[2000005];bool in(int x,int y){ return x>=0&&x<row*2+3&&y>=0&&y<col*2+3; }int GetId(int x,int y){ return x*(col*2+3)+y; }void Print(int A[],int N){    for(int i=0;i<=N;i++) printf("%d ",A[i]);    puts("");}void init(){    for(int i=0;i<=M;i++) tempx[i]=wx[i],tempy[i]=wy[i];    sort(tempx,tempx+M+1);    sort(tempy,tempy+M+1);    row=col=0;    for(int i=1;i<=M;i++) if(tempx[i]!=tempx[row]) tempx[++row]=tempx[i];    for(int i=1;i<=M;i++) if(tempy[i]!=tempy[col]) tempy[++col]=tempy[i];}struct node{    int x,y;    node(int x=0,int y=0):x(x),y(y){}};queue<node> que;void bfs(){    memset(maze,-1,sizeof(maze));    for(int i=1;i<=M;i++)    {        int x1=lower_bound(tempx,tempx+row+1,wx[i-1])-tempx;        int y1=lower_bound(tempy,tempy+col+1,wy[i-1])-tempy;        int x2=lower_bound(tempx,tempx+row+1,wx[i])-tempx;        int y2=lower_bound(tempy,tempy+col+1,wy[i])-tempy;        x1=x1*2+1; y1=y1*2+1; x2=x2*2+1; y2=y2*2+1;        if(x1==x2)        {            if(y1>y2) swap(y1,y2);            for(int st=y1;st<=y2;st++) maze[GetId(x1,st)]=1;        }        else if(y1==y2)        {            if(x1>x2) swap(x1,x2);            for(int st=x1;st<=x2;st++) maze[GetId(st,y1)]=1;        }    }    while(!que.empty()) que.pop();    que.push(node(0,0));    maze[GetId(0,0)]=-1;    while(!que.empty())    {        node& t=que.front();  que.pop();        int x=t.x,y=t.y;        for(int i=0;i<4;i++)        {            int nx=x+dx[i];            int ny=y+dy[i];            if(!in(nx,ny)) continue;            int id=GetId(nx,ny);            if(ny%2==0&&(i==0||i==2)&&in(nx,ny-1)&&in(nx,ny+1))            {                int a=(ny-1)/2;                int b=(ny+1)/2;                if(tempy[b]-tempy[a]-1<=0) continue;            }            if(nx%2==0&&(i==1||i==3)&&in(nx-1,ny)&&in(nx+1,ny))            {                int a=(nx-1)/2;                int b=(nx+1)/2;                if(tempx[b]-tempx[a]-1<=0) continue;            }            if(maze[id]==-1){ que.push(node(nx,ny)); maze[id]=0; }        }    }}LL solve(){    LL ret=0;    bfs();    for(int i=0;i<row*2+3;i++)        for(int j=0;j<col*2+3;j++)    {        int p=GetId(i,j);        if(maze[p]==0) continue;        int a=(j+1)/2,b=(j-1)/2;        int c=(i+1)/2,d=(i-1)/2;        if(i%2==1&&j%2==1) ret++;        else if(i%2==1) ret+=(LL)tempy[a]-tempy[b]-1;        else if(j%2==1) ret+=(LL)tempx[c]-tempx[d]-1;        else ret+=(LL)(tempx[c]-tempx[d]-1)*(tempy[a]-tempy[b]-1);    }    return ret;}int main(){    while(scanf("%d",&M)!=EOF)    {        wx[0]=0,wy[0]=0;        for(int i=1;i<=M;i++)        {            char c;            int d;            scanf(" %c %d",&c,&d);            wx[i]=wx[i-1]; wy[i]=wy[i-1];            if(c==‘U‘) wx[i]-=d;            else if(c==‘D‘) wx[i]+=d;            else if(c==‘L‘) wy[i]-=d;            else if(c==‘R‘) wy[i]+=d;            //printf("%d %d\n",wx[i],wy[i]);        }        init();        printf("%I64d\n",solve());    }    return 0;}
时间: 2024-11-12 03:53:31

Codeforces243C-Colorado Potato Beetle(离散化+bfs)的相关文章

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

离散化+BFS HDOJ 4444 Walk

题目传送门 1 /* 2 题意:问一个点到另一个点的最少转向次数. 3 坐标离散化+BFS:因为数据很大,先对坐标离散化后,三维(有方向的)BFS 4 关键理解坐标离散化,BFS部分可参考HDOJ_1728 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <queue> 10 #include <vector> 11 #include

HDU 4444 离散化+bfs 注意细节

Walk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1972    Accepted Submission(s): 308 Problem Description Biaoge is planning to walk to amusement park. The city he lives can be abstracted as

[ An Ac a Day ^_^ ] hdu 5925 Coconuts 离散化+BFS求连通块

东北赛根本就没看懂的的题目…… 也用到了离散化 1e9的x y范围 200个坏点 很典型的离散化数据范围 还是不太为什么离散化的遍历下标都要从1开始…… 所以说只做这道题对离散化的理解还不是很深刻…… 因为可能换一道题又不会了 还是要多做啊 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<

hdu 4400 Mines(离散化+bfs+枚举)

Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all people in time before any mine explodes. Now the police want all the mines be ignited. The police will take many operations to do the job. In each ope

[考试反思]0122省选模拟12:延迟

博客咕过了一年我也就忘了我考试状态了2333. T1是弱智题但是没想...写个暴力跑路了(时间不够,主要投在T2/3上了) 然而其实想到了一个乱搞,觉得能得分的概率不大,结果数据奇水完全不对的玩意还有20分,然而我并没有写... 然而T2写的是正解,虽说没有其他人的状压优秀,T了一个细节WA了一个拿了80分,凑合吧. 然后T3时间不多的时候写的,拿个暴力,想到了正解大概怎么写但是没有写,太恶心. 考后改题写了写,一下午就过去了...一晚上也就过去了...弄得跟我颓废了半天一样... 然而是真xx

省选模拟12 题解

A. Colorado Potato Beetle 暴力做法是直接bfs. 优化的方法是离散化. 将特殊的点的横纵坐标抽出来,然后用这些横纵坐标为1e12*1e12分成一个个块,容易发现每个块内的状态是一致的. 然后用与暴力类似的方法即可,注意最后统计的是每个块的实际大小. B. Distinct Paths 观察可知数据范围欺骗了你. 似乎剪枝(注意去重复状态)的搜索就能过. 一个更合理的做法是因为行是单调不降的,状压每个颜色的最早出现的列就好了. 但是还是需要一些玄学剪枝. C. 回忆树 容

东北育才 数论专场第2场

本人弃坑了! comb 简单求组合数,方法很多. maths 转化公式,发现积性,发现规律后乱搞.(居然给时6s) beetle 离散化后BFS,模拟. divisorful 这道题打打表就够了.(恶心,想吐) 居然rank 1,不想多说了.

uva 12171 hdu 1771 Sculpture

//这题从十一点开始写了四十分钟 然后差错一小时+ 要吐了 这题题意是给很多矩形的左下角(x,y,z最小的那个角)和三边的长(不是x,y,z最大的那个角T-T),为组成图形的面积与表面积(包在内部的之算体积不算表面积) 解法:离散化+bfs,先把范围扩大(相当于在周围加上空气),然后bfs,遇到表面积直接加入,遇到非长方体的部分也直接加入,最后用总体积减去空气的体积,这样就可以把内部的体积计算进来而不计算其表面积.因为坐标范围比较大,要先离散化. //其实我对这题一直耿耿于怀,当年没进省队多少与