GRYZ[寒假模拟赛]

GRYZ娱乐时刻

【题目描述】

      无聊的hyxzc不想写代码了,于是他开始玩游戏——洛克王国。众所周知,洛克王国是一个非常好玩的游戏(至少在hyxzc眼中是这样的)。这天,hyxzc登上他的洛克王国账号,开始了新的一天的颓废之旅。

hyxzc是一个高傲的人,他想把自己的宠物都升到100级(没办法,强迫症),今天是洛克王国4周年纪念日,所以奖励非常多,正当小洛克们欢快的庆祝周年的时候,坏坏的恩佐又出来捣乱了,(众所周知,恩佐是一个超级大坏蛋,总想一些办法去损害洛克王国,而守护洛克王国是每位小洛克的责任)。这次,恩佐无意在黑魔法中发现了召唤远古恶龙的方法。并且召唤了n条恶龙,而你的任务则是消灭这n条恶龙, 本次任务奖励有大量经验,能够让宠物更快的升级,所以hyxzc便心动了。

hyxzc一共有m个宠物可以召唤,而每个宠物的等级各不相同,等级为x的宠物只能干掉小于等于x的恶龙,且每只宠物只能干掉一只恶龙,因为宠物还要去找自己的小伙伴去玩耍呢,并且你需要花费x个洛克贝为宠物恢复活力。hyxzc可不是一个大方的家伙,他希望花最少的洛克贝来完成这个任务。而洛克王国的防沉迷告诉hyxzc,他只有1秒钟的时间去思考如何召唤宠物,于是hyxzc便向你求助,你只需要输出他的最少花费即可,若无法完全杀掉恶龙,则输出“Loowater is doomed!”。

【输入格式】

输入包含T组数据,每组数据的第一行为正整数n和m;以下n行每行为一个整数,即恶龙的等级,以下m行为一个整数,即每个宠物的等级,输入结束标记为n=m=0;

【输出格式】

对于每组数据,输出最少花费。

【样例输入】

2 3

5

4

7

8

4

2 1

5

5

10

0 0

【样例输出】

11

Loowater is doomed!

【数据范围】

0

对于20%的数据:0<=20;0<=100000;

对于40%的数据:0<=200;0<=100000;

对于60%的数据:0<=2000;0<=100000;

对于100%的数据:0<=20000;0<=100000;

       GRYZ追击

自己的答案(贪心算法);

#include

#include

using namespace std;

#include

#include

int n,m;

int el[20001],cw[20001];

void px(int n,int m)

{

       sort(el+1,el+n+1);

       sort(cw+1,cw+m+1);

}

int main()

{

       freopen("hyxzc.in","r",stdin);

       freopen("hyxzc.out","w",stdout);

       while(scanf("%d%d",&n,&m)==2&&(n!=0&&m!=0))

       {

              long long sum=0;

              memset(el,0,sizeof(el));

              memset(cw,0,sizeof(cw));

              for(int i=1;i<=n;++i)

              scanf("%d",&el[i]);

              for(int i=1;i<=m;++i)

              scanf("%d",&cw[i]);

              px(n,m);

              int ell=1,cwl=1;

              while(ell<=n&&cwl<=m)

              {

                     if(el[ell]<=cw[cwl])

                     {

                            sum+=cw[cwl];

                            ell++;

                            cwl++;

                     }

                     if(el[ell]>cw[cwl]&&cw[cwl]!=0)

                     {

                            cwl++;

                     }

                    

              }

              if(ell==n+1)

              cout<<sum<<endl;

              if(cwl==m+1&&ell<=n)

              printf("Loowater is doomed!\n");

             

       }

       fclose(stdin);

    fclose(stdout);

       return 0;

}

GRYZ追击时刻

XYD过完年后高高兴兴的回到了GRYZ,然后他发现可爱的Robot已经在这里等待了3天,由于Robot跑的很慢,所以她正在准备施展魔法,逮住 XYD。

       XYD知道,除了男生宿舍,其他的地方都会被Robot宝宝魔法控制(因为宝宝是一个可爱的女孩子),如果XYD被控制之后,就会发生很可怕的 事情。。。

所以,XYD一定要尽快赶回男生宿舍。

       GRYZ可以用一个N*M(N,M<=50)的地图表示,地图上有5种符号:"X S D . *" 。其中“X”处有可怕的兔兔(兔兔可能很多),XYD和Robot都不能经过。

       "."表示XYD和魔法都能经过的地方。

       “*”表示Robot的位置,“S”表示XYD起始位置,“D”表示男生宿舍。

       xyd每秒钟可以向相邻位置移动,Robot的魔法也会向相邻的地方蔓延(从已覆盖的区域,开始只覆盖*点)。众所周知,宝宝魔法就像是一股水流。     

求XYD回到男生宿舍的最短时间,如果XYD回不到男生宿舍,就有可能被迫以身相许,那么他就会高兴的大喊一声“I Love xxx!!!”。(这就是很可怕的事情)

【输入格式】

第一行为正整数n和m;以下n行m列为地图。

【输出格式】

如果能成功回到男生宿舍输出最短时间,否则输出“I Love xxx!!!”(不包括双引号)

【样例输入】

3 3

D.*

.S.

【样例输出】

3

【样例输入】

3 3

D.*

..S

【样例输出】

I Love xxx!!!

自己的答案(正确):

#include

using namespace std;

#include

#include

#define M 55

int map[M][M],head=0,tail=0,q[M*M][2];

int xx[4]={0,0,1,-1};

int yy[4]={1,-1,0,0};

int tim[M][M],bu[M][M];

int n,m,xk,yk,xz,yz;

void input()

{

       scanf("%d%d",&n,&m);

       char ch[M];

       memset(tim,99,sizeof(tim));

       for(int i=1;i<=n;++i)

       {

      scanf("%s",ch+1);//从ch[1]读入字符串,scanf不读入回车和字符

         for(int j=1;j<=m;++j)

         {

            if(ch[j]=='.')

            map[i][j]=0;

            if(ch[j]=='*')

            {

                   tail++;

                   q[tail][0]=i;//队列储存着

                   q[tail][1]=j;

                   tim[i][j]=0;

                  

                }

              if(ch[j]=='S')//起始点

              {

                     xk=i;

                     yk=j;

             

                    

              }

              if(ch[j]=='D')//终点

              {

                     map[i][j]=1;

                     xz=i;yz=j;

              }

              if(ch[j]=='X')

              {

                     map[i][j]=2;

              }

             

              }

         }

}

void search_time()

{

      

       while(head

       {

              head++;

              for(int i=0;i<4;++i)//4种走的情况

              {

                     int nx=q[head][0]+xx[i],ny=q[head][1]+yy[i];

                     if(nx&&ny&&nx<=n&&ny<=m&&!map[nx][ny]&&tim[nx][ny]>tim[q[head][0]][q[head][1]]+1)

                     {

                        tim[nx][ny]=tim[q[head][0]][q[head][1]]+1;//更新每个点洪水到达最短时间

                            tail++;

                            q[tail][0]=nx;

                            q[tail][1]=ny;

                           

                     }

              }

       }

      

}

void search_bu()

{

       q[1][0]=xk;//队列开始存储人走的路径

       q[1][1]=yk;

       memset(bu,99,sizeof(bu));//把步数赋值一个大数,好进行下面的更新

       bu[xk][yk]=0;

       head=0;

       tail=1;

       while(head

       {

              head++;

              if(q[head][0]==xz&&q[head][1]==yz)

              break;

              for(int i=0;i<4;++i)

              {

                     int nx=q[head][0]+xx[i];

                     int ny=q[head][1]+yy[i];

                     if(nx&&ny&&nx<=n&&ny<=m&&map[nx][ny]<2&&bu[nx][ny]>bu[q[head][0]][q[head][1]]+1&&tim[nx][ny]>bu[q[head][0]][q[head][1]]+1)//虽然说人比魔法先到该点,但是当魔法到来的时候,人还没有到下一个点,这样还是不行

                  {

                        bu[nx][ny]=bu[q[head][0]][q[head][1]]+1;

                        ++tail;

                        q[tail][0]=nx;

                        q[tail][1]=ny;

                     }

              }

       }

       if(bu[xz][yz]==1667457891)//前面赋值的99的真实值

       printf("I Love xxx!!!");

       else printf("%d",bu[xz][yz]);

       return;

}

int main()

{

       freopen("clikar1.in","r",stdin);

       freopen("clikar.out","w",stdout);

       input();

       search_time();

       search_bu();

       fclose(stdin);

       fclose(stdout);

       return 0;

}

GRYZ就餐时刻

 

【题目描述】

寒假,大家都回家过年去了,只有GRYZ苦逼的竞赛生们还在学校上课。众所周知,有人的地方就需要有饭,但是食堂的大爷们都回家了,我们只能依靠外卖。已知那是一个非常大的外卖店,有专业的盒饭生产设备,为了保证GRYZ的孩子们每顿饭能吃好吃的饭菜,它们总会将a点生产出的盒饭运往加热处加热后再运往b点装车。这些部门非常的高能,它们有时可以生产盒饭,有时又能变身成装车点(不要问我为什么)。

有些部门之间有专门的传送带连接,店长是个非常珍惜时间的人,他希望盒饭从生产出来到运走所花费的时间尽可能的短,但是店长又是一个超级懒人,所以他把计算的工作交给了你

【输入格式】

第一行两个整数n、m,n表示部门数量,m表示传送带数量。出于方便,1号部门是加热处。

接下来m行,每行三个整数u、v、w,表示有一条从u部门到v部门的传送带,传送过去需要w个单位时间。注意传送带是单向的。

接下来一个整数q,表示有q次运送。

接下来q行,每行两个数a、b,表示这一次要将产品从a部门运送到b部门。

【输出格式】

输出q行,每行一个整数,表示这次运送最少需要的时间。若没有传送方案,输出-1。

【样例输入】

5 5

1 2 3

1 3 5

4 1 7

5 4 1

5 3 1

3

4 2

5 3

2 3

【样例输出】

10

13

-1

【数据规模与约定】

30%的数据,n≤100,m≤500,w=1

60%的数据,n≤100,m≤5000

另20%的数据,q=1

100%的数据,2≤n≤3000,m≤100000,2≤a,b≤n,

q≤100000,1≤u,v≤n,1≤w≤10000

有些部门之间可能有多条传送带。

边表:一条边里储存着指向同一起点的上一条边,是边指向边

邻接表:点指向点,1—>3à5,表示1-3,和1—5这两条边,

由点指向点,好理解些

答案:

#include

using namespace std;

#include

#include

#define M 100001

#define N 3001

#define maxx 999999

struct Edge{

       int u,v,w,next;

};

Edge edge1[M],edge2[M];

int dis1[N],dis2[N];

int n,m,head1[N],head2[N];

int visit1[N]={0},visit2[N]={0};

void add1(int,int,int,int);

void add2(int,int,int,int);

void djk();

void input();

void sc();

int main()

{

       freopen("eat.in","r",stdin);

       freopen("eat.out","w",stdout);

       memset(dis2,127,sizeof(dis2));

       memset(dis1,127,sizeof(dis1));

       input();

       djk();

       sc();

       fclose(stdin);

       fclose(stdout);

       return 0;

}

void input()

{

       scanf("%d%d",&n,&m);

       int u1,v1,w1;

       for(int i=1;i<=m;++i)

       {

              scanf("%d%d%d",&u1,&v1,&w1);

              add1(u1,v1,w1,i);

              add2(v1,u1,w1,i);

       }

       return;

      

}

void sc()

{

       int q,a,b;

       scanf("%d",&q);

       for(int i=1;i<=q;++i)

       {

              scanf("%d%d",&a,&b);

              if(dis1[b]+dis2[a]

              printf("%d\n",dis1[b]+dis2[a]);

              else printf("-1");

       }

       return;

}

void add1(int u1,int v1,int w1,int i)

{

 

       edge1[i].u=u1;

       if(u1==1)

       dis1[v1]=w1;

       edge1[i].v=v1;

       edge1[i].w=w1;

       edge1[i].next=head1[u1];

       head1[u1]=i;

}

void add2(int u1,int v1,int w1,int i)

{

      

       edge2[i].u=u1;

       if(u1==1)

       dis2[u1]=w1;

       edge2[i].v=v1;

       edge2[i].w=w1;

       edge2[i].next=head2[u1];

       head2[u1]=i;

}

void djk()

{

       dis1[1]=0;

       for(int i=1;i<=n-1;++i)

       {

              int min1=maxx,k=0;

              for(int j=1;j<=n;++j)

              {

                     if(dis1[j]

                     {

                            k=j;

                            min1=dis1[j];

                     }

              }

              if(k==0) break;

              visit1[k]=1;

              for(int l=head1[k];l!=0;l=edge1[l].next)

              {

                     if(dis1[edge1[l].v]>dis1[edge1[l].u]+edge1[l].w)

                     dis1[edge1[l].v]=dis1[edge1[l].u]+edge1[l].w;

              }

       }

       dis2[1]=0;

       for(int i=1;i<=n-1;++i)

       {

              int min1=maxx,k=0;

              for(int j=1;j<=n;++j)

              {

                     if(dis2[j]

                     {

                            k=j;

                            min1=dis2[j];

                     }

              }

              if(k==0) break;

              visit2[k]=1;

              for(int l=head2[k];l!=0;l=edge2[l].next)

              {

                     if(dis2[edge2[l].v]>dis2[edge2[l].u]+edge2[l].w)

                     dis2[edge2[l].v]=dis2[edge2[l].u]+edge2[l].w;

              }

       }

}

 

posted on 2016-03-18 06:06  142141241  阅读(138)  评论(0编辑  收藏  举报

导航