水滴模拟问题(误)hdu5336

<p>
</p>

XYZ and Drops

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1179    Accepted Submission(s): 370


Problem Description
XYZ is playing an interesting game called "drops". It is played on a  rc  grid. Each grid cell is either empty, or occupied by a waterdrop. Each waterdrop has a property "size". The waterdrop cracks when its size is larger than 4, and produces 4 small drops moving towards 4 different directions (up, down, left and right).

In every second, every small drop moves to the next cell of its direction. It is possible that multiple small drops can be at same cell, and they won't collide. Then for each cell occupied by a waterdrop, the waterdrop's size increases by the number of the small drops in this cell, and these small drops disappears. 

You are given a game and a position ( x y ), before the first second there is a waterdrop cracking at position ( x y ). XYZ wants to know each waterdrop's status after  T  seconds, can you help him?

1r100 1c100 1n100 1T10000
 

Input
The first line contains four integers  r c n  and  T n  stands for the numbers of waterdrops at the beginning. 
Each line of the following  n  lines contains three integers  xi yi sizei , meaning that the  i -th waterdrop is at position ( xi yi ) and its size is  sizei . ( 1sizei4 )
The next line contains two integers  x y

It is guaranteed that all the positions in the input are distinct. 

Multiple test cases (about 100 cases), please read until EOF (End Of File).
 

Output
n  lines. Each line contains two integers  Ai Bi
If the  i -th waterdrop cracks in  T  seconds,  Ai=0 Bi=  the time when it cracked. 
If the  i -th waterdrop doesn't crack in  T  seconds,  Ai=1 Bi=  its size after  T  seconds.
 

Sample Input
    
    
4 4 5 10 2 1 4 2 3 3 2 4 4 3 1 2 4 3 4 4 4
 

Sample Output
    
    
0 5 0 3 0 2 1 3 0 1
 

Author
XJZX
 

Source
 

Recommend
wange2014

本来想的是图的思路,然后没优化,敲出来代码实在太长了。。。。也因为太长,有各种小错。。。反正就是wa的,先贴上错误的代码


//题目是若干水滴若是体积>4则会炸裂为4个方向的速度为1格/s的小水滴。
//小水滴不相撞,但是遇到大水滴就会融进大水滴里面。当大水滴体积>4则又炸裂开来。
//每个大水滴因为初始情况下肯定是1~4的size,所以要接受到足够的小水滴才会炸裂。
//接收到的小水滴来自于同行或者同列的大水滴。如果最近的那个大水滴体积不到4则那个方向的小水滴暂时无法到达这个水滴而被那个大水滴吸收
//需要记录当前的size,然后四个方向找最近的大水滴。
//采用顺序,找当前这些大水滴炸了之后最短时间内状态改变的大水滴。
//如果大水滴接受到小水滴之后也炸了,就把这个大水滴也加入数组,否则将size+1
.//当找到这个大水滴的某个方向的大水滴之后,当前这个大水滴在这个方向的小水滴变为0
//当这个大水滴的四个方向的小水滴都为0或者找不到大水滴之后,这个大水滴就进入已结束数组。
//而新炸裂的大水滴进入未结束的数组,即还有小水滴不为0并且还能找到在数组之外的大水滴。
//当前拓展未结束数组,循环数组找出距离最近的大水滴,并对当前大水滴进行操作,t=t数组中对应的那个大水滴的t+distance。
//如果这个大水滴还没有炸,那么t需要不断更新。
//大水滴需要记录是否炸裂,炸裂了则输出炸裂时间,没炸裂的话输出当前size        
//在这里注一件事儿,这台电脑的vim的输入输出我一直没调好,于是只有make功能。。。        
//于是今天又怒搜索了很久。。。重定向什么的,找了不少。。。然而还是没有什么用。。        
//于是怒了的我选择了Code::Blocks。。。vim的界面还是长得不错的,但是如果需要运行程序的话,可以选择复制粘贴到Code::Blocks上去运行       
 //我知道vim是可以用in.txt作为输入的,但是实在是不知到该怎么设置,in.txt位置在哪呢,默认的in.txt在哪呢,修改输入输出的文件的语句怎么写?       
 //于是我放弃了在vim上面输入输出的想法。还好还有Clock::Blocks。。。       
 //然后继续敲代码吧
//更新。。当当前这个大水滴炸裂之后,它的上下左右连接的大水滴就要更新状态,即当它炸了之后就不是实体的大水滴了,
//那么left的lbig=nope[i].rbig,right的rbig=nope[i].lbig,上下同理
//但是当前大水滴的上下左右是不需要改变的,上下左右的意义在于,当前这个大水滴炸裂之后上下左右的水滴各自会打到哪个大水滴处

<span style="font-size:10px;">#include<iostream>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<algorithm>
#define N 10010
#define min(x,y)((x<y)?x:y)
using namespace std;
int r,c,n,t,X,Y;
class A{
    public:
        int a;
};
class Nope{
    public:
        int ubig,dbig,lbig,rbig;//记录前后左右连接的大水滴
        int usmall,dsmall,lsmall,rsmall;//记录自己炸裂之后发出的前后左右的小水滴是否被吸收了
        bool flog;//为0代表还没炸
        int size;//大水滴的size
        int t;//大水滴的炸裂时间t
        int x,y;//大水滴的坐标
}nope[N];
int main()
{
    while(cin>>r>>c>>n>>t)
    {
        int map[1010][1010];//用来保存地图上的大水滴的位置对应的序号
        memset(map,0,sizeof(map));
        for(int i=1;i<=n;i++)
        {
            cin>>nope[i].x>>nope[i].y>>nope[i].size;//输入每个大水滴的数据
            nope[i].ubig=0,nope[i].dbig=0,nope[i].lbig=0,nope[i].rbig=0;
            nope[i].usmall=1,nope[i].dsmall=1,nope[i].lsmall=1,nope[i].rsmall=1;
            nope[i].flog=0;
            map[nope[i].x][nope[i].y]=i;
        }
        cin>>X>>Y;//最初炸裂的位置。
    //    cout<<"XY"<<endl;
        map[X][Y]=n+1;
        nope[n+1].x=X,nope[n+1].y=Y;
        nope[n+1].ubig=0,nope[n+1].dbig=0,nope[n+1].lbig=0,nope[n+1].rbig=0;
        nope[n+1].usmall=1,nope[n+1].dsmall=1,nope[n+1].lsmall=1,nope[n+1].rsmall=1;
        nope[n+1].t=0;
        vector<int> finish,ing,no;//分别是:四个小水滴都不再对剩下大水滴造成影响的,本身已炸但是小水滴还对剩下还有影响的,本身还没炸的。
    //    memset(finish,0,sizeof(finish));
    //    memset(ing,0,sizeof(ing));
    //    memset(no,0,sizeof(no));//ok,初始化完成
        finish.clear();
        ing.clear();
        no.clear();
        ing.push_back(n+1);
        int T=0;//当前进行到的时间T
        //先建图
        int ii=0;
        for(int i=1;i<=r;i++)//横向的图
        {
            ii=0;
            for(int j=1;j<=c;j++)
            {
                if(map[i][j])
                {
                    if(ii==0)
                    {
                        ii=map[i][j];
                        continue;
                    }
                    else 
                    {
                        nope[ii].dbig=map[i][j];
                        nope[map[i][j]].ubig=ii;
                        ii=map[i][j];
                    }
                }
            }
        }
        for(int i=1;i<=c;i++)//纵向的图
        {
            ii=0;
            for(int j=1;j<=r;j++)
            {
                if(map[j][i])
                {
                    if(ii==0)
                    {
                        ii=map[j][i];
                        continue;
                    }
                    else 
                    {
                        nope[ii].rbig=map[j][i];
                        nope[map[j][i]].lbig=ii;
                        ii=map[j][i];
                    }
                }
            }
        }
    //    cout<<"t"<<T<<endl;
    //    if(ing.empty())
        //    cout<<"ing.empty"<<endl;
        while(T<=t&&!ing.empty())
        {
            cout<<"ing"<<ing.size()<<"ing0"<<ing[0]<<endl;
            T=t+1;
            //cout<<"T=t+1"<<T<<endl;
            //cout<<"ing.size"<<ing.size()<<endl;
            for(int i=0;i<ing.size();i++)//先找出还未添加的最小的T,
            {
            //    cout<<"i"<<i<<endl;
                if(nope[ing[i]].lbig>0&&nope[ing[i]].lsmall)
                {
                    T=min(nope[ing[i]].t+(nope[ing[i]].x-nope[nope[ing[i]].lbig].x),T);
                //    cout<<"T1"<<T<<endl;
                }
                if(nope[ing[i]].rbig>0&&nope[ing[i]].rsmall)
                {
                    T=min(nope[ing[i]].t+(nope[nope[ing[i]].rbig].x-nope[ing[i]].x),T);
                //    cout<<"T2"<<T<<endl;                    
                }
                if(nope[ing[i]].ubig>0&&nope[ing[i]].usmall)
                {
                    T=min(nope[ing[i]].t+(nope[ing[i]].y-nope[nope[ing[i]].ubig].y),T);
                //    cout<<"T3"<<T<<endl;                    
                }
                if(nope[ing[i]].dbig>0&&nope[ing[i]].dsmall)
                {
                    T=min(nope[ing[i]].t+(nope[nope[ing[i]].dbig].y-nope[ing[i]].y),T);
                //    cout<<"T4"<<T<<endl;                    
                }
            }
        //    cout<<"T"<<T<<endl;
            if(T<=t)
            {
                for(int i=0;i<ing.size();i++)//先找出还未添加的最小的T,
                {
                    if(nope[ing[i]].lbig>0&&nope[ing[i]].lsmall!=0)
                    //这里举个栗子,如果T和当前找到的t相等,那么这里找到的对应的大水滴就要吸收当前这个小水滴。
                    {
                        if(T==nope[ing[i]].t+nope[ing[i]].x-nope[nope[ing[i]].lbig].x)
                        {
                            nope[nope[ing[i]].lbig].t=T;
                            if(nope[ing[i]].rbig&&nope[nope[ing[i]].rbig].lsmall)
                            {
                                nope[nope[ing[i]].lbig].rbig=nope[ing[i]].rbig;
                                nope[nope[ing[i]].rbig].lbig=nope[ing[i]].lbig;
                            }
                            else
                            {
                                nope[nope[ing[i]].lbig].rbig=0;
                            }
                            if(nope[nope[ing[i]].lbig].size>3)
                            {
                                nope[nope[ing[i]].lbig].size=5;
                                ing.push_back(nope[ing[i]].lbig);
                                std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                 pos = find(no.begin(),no.end(),nope[ing[i]].lbig);
                                  if (pos != no.end()) 
                                {
                                   no.erase(pos);
                                  }
                            }
                            else 
                            {
                                nope[nope[ing[i]].lbig].size+=1;
                            }
                            //截至上面,是处理左右节点的。下面处理自己这个节点。如果四个小水滴为0或者不会影响到别的大水滴了,则finish。
                            nope[ing[i]].lsmall=0;
                            if(nope[ing[i]].lbig==0||nope[ing[i]].lsmall==0)
                            if(nope[ing[i]].rbig==0||nope[ing[i]].rsmall==0)
                            if(nope[ing[i]].ubig==0||nope[ing[i]].usmall==0)
                            if(nope[ing[i]].dbig==0||nope[ing[i]].dsmall==0)
                            {
                                finish.push_back(i);
                                std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                 pos = find(ing.begin(),ing.end(),i);
                                  if (pos != ing.end()) 
                                {
                                   ing.erase(pos);
                                  }
                            }
                        }
                    }
                //    for(int i=0;i<ing.size();i++)
                //    {
                        if(nope[ing[i]].rbig>0&&nope[ing[i]].rsmall!=0)
                        {
                            if(T==nope[ing[i]].t+nope[nope[ing[i]].rbig].x-nope[ing[i]].x)
                            {    nope[nope[ing[i]].rbig].t=T;                    
                                if(nope[ing[i]].lbig&&nope[nope[ing[i]].lbig].rsmall)
                                {
                                    nope[nope[ing[i]].rbig].lbig=nope[ing[i]].lbig;
                                    nope[nope[ing[i]].lbig].rbig=nope[ing[i]].rbig;
                                }
                                else
                                {
                                    nope[nope[ing[i]].rbig].lbig=0;
                                }
                                if(nope[nope[ing[i]].rbig].size>3)
                                {
                                    nope[nope[ing[i]].rbig].size=5;
                                    ing.push_back(nope[ing[i]].rbig);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(no.begin(),no.end(),nope[ing[i]].rbig);
                                      if (pos != no.end()) 
                                    {
                                       no.erase(pos);
                                      }
                                }
                                else 
                                {
                                    nope[nope[ing[i]].rbig].size+=1;
                                }
                                //截至上面,是处理左右节点的。下面处理自己这个节点。如果四个小水滴为0或者不会影响到别的大水滴了,则finish。
                                nope[ing[i]].rsmall=0;
                                if(nope[ing[i]].lbig==0||nope[ing[i]].lsmall==0)
                                if(nope[ing[i]].rbig==0||nope[ing[i]].rsmall==0)
                                if(nope[ing[i]].ubig==0||nope[ing[i]].usmall==0)
                                if(nope[ing[i]].dbig==0||nope[ing[i]].dsmall==0)
                                {
                                    finish.push_back(i);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(ing.begin(),ing.end(),i);
                                      if (pos != ing.end()) 
                                    {
                                       ing.erase(pos);
                                      }
                                }
                            }

                        }
                        if(nope[ing[i]].ubig>0&&nope[ing[i]].usmall!=0)
                        {
                            if(T==nope[ing[i]].t+nope[ing[i]].y-nope[nope[ing[i]].ubig].y)
                            {
                                nope[nope[ing[i]].ubig].t=T;                            
                                if(nope[ing[i]].dbig&&nope[nope[ing[i]].dbig].usmall)
                                {
                                    nope[nope[ing[i]].ubig].dbig=nope[ing[i]].dbig;
                                    nope[nope[ing[i]].dbig].ubig=nope[ing[i]].ubig;
                                }
                                else
                                {
                                    nope[nope[ing[i]].ubig].dbig=0;
                                }
                                if(nope[nope[ing[i]].ubig].size>3)
                                {
                                    nope[nope[ing[i]].ubig].size=5;
                                    ing.push_back(nope[ing[i]].ubig);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(no.begin(),no.end(),nope[ing[i]].ubig);
                                      if (pos != no.end()) 
                                    {
                                       no.erase(pos);
                                      }
                                }
                                else 
                                {
                                    nope[nope[ing[i]].ubig].size+=1;
                                }
                                    //截至上面,是处理左右节点的。下面处理自己这个节点。如果四个小水滴为0或者不会影响到别的大水滴了,则finish。
                                nope[ing[i]].usmall=0;
                                if(nope[ing[i]].lbig==0||nope[ing[i]].lsmall==0)
                                if(nope[ing[i]].rbig==0||nope[ing[i]].rsmall==0)
                                if(nope[ing[i]].ubig==0||nope[ing[i]].usmall==0)
                                if(nope[ing[i]].dbig==0||nope[ing[i]].dsmall==0)
                                {
                                    finish.push_back(i);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(ing.begin(),ing.end(),i);
                                      if (pos != ing.end()) 
                                    {
                                       ing.erase(pos);
                                      }
                                }
                            }
                        }
                        if(nope[ing[i]].dbig>0&&nope[ing[i]].dsmall!=0)
                        {
                            if(T==nope[ing[i]].t+nope[nope[ing[i]].dbig].y-nope[ing[i]].y)
                            {
                                nope[nope[ing[i]].dbig].t=T;                            
                                if(nope[ing[i]].ubig&&nope[nope[ing[i]].ubig].dsmall)
                                {
                                    nope[nope[ing[i]].dbig].ubig=nope[ing[i]].ubig;
                                    nope[nope[ing[i]].ubig].dbig=nope[ing[i]].dbig;
                                }
                                else
                                {
                                    nope[nope[ing[i]].dbig].rbig=0;
                                }
                                if(nope[nope[ing[i]].dbig].size>3)
                                {
                                    nope[nope[ing[i]].dbig].size=5;
                                    ing.push_back(nope[ing[i]].dbig);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(no.begin(),no.end(),nope[ing[i]].dbig);
                                      if (pos != no.end()) 
                                    {
                                       no.erase(pos);
                                      }
                                }
                                else 
                                {
                                    nope[nope[ing[i]].dbig].size+=1;
                                }
                                //截至上面,是处理左右节点的。下面处理自己这个节点。如果四个小水滴为0或者不会影响到别的大水滴了,则finish。
                                nope[ing[i]].dsmall=0;
                                if(nope[ing[i]].lbig==0||nope[ing[i]].lsmall==0)
                                if(nope[ing[i]].rbig==0||nope[ing[i]].rsmall==0)
                                if(nope[ing[i]].ubig==0||nope[ing[i]].usmall==0)
                                if(nope[ing[i]].dbig==0||nope[ing[i]].dsmall==0)
                                {
                                    finish.push_back(i);
                                    std::vector<int>::iterator pos;//删除。。。有点不靠谱
                                     pos = find(ing.begin(),ing.end(),i);
                                      if (pos != ing.end()) 
                                    {
                                       ing.erase(pos);
                                      }
                                }
                            }
                        }
                }

            }
            cout<<"ing"<<ing.size()<<"ing0"<<ing[0]<<endl;
            
        }
        for(int i=1;i<=n;i++)//输出
        {
            if(nope[i].size>4)
                cout<<"0 "<<nope[i].t<<endl;
            else 
                cout<<"1 "<<nope[i].size<<endl;
        }
    }
    return 0;
}
</span>




//机房浏览器好像有点崩。。先上传吧,等会儿回寝室了再修改。



考虑到数据量的话,其实可以用更加暴力的方法的。for i 0~t,模拟每一滴小水滴前进一布之后的情况,就可以了。

但是我没写代码,贴一下别人的代码网址:
http://blog.csdn.net/zjck1995/article/details/47154715

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值