• GRYZ[寒假模拟赛]


    GRYZ娱乐时刻

    【题目描述】

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

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

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

    【输入格式】

    输入包含T组数据,每组数据的第一行为正整数nm;以下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! ");

                 

           }

           fclose(stdin);

        fclose(stdout);

           return 0;

    }

    GRYZ追击时刻

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

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

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

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

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

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

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

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

    【输入格式】

    第一行为正整数nm;以下nm列为地图。

    【输出格式】

    如果能成功回到男生宿舍输出最短时间,否则输出“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点装车。这些部门非常的高能,它们有时可以生产盒饭,有时又能变身成装车点(不要问我为什么)。

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

    【输入格式】

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

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

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

    接下来q行,每行两个数ab,表示这一次要将产品从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≤100m≤500w=1

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

    20%的数据,q=1

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

    q≤1000001≤u,v≤n1≤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 ",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;

                  }

           }

    }

     

  • 相关阅读:
    203. Remove Linked List Elements
    86. Partition List
    143. Reorder List
    876. Middle of the Linked List
    246. Strobogrammatic Number
    202. Happy Number
    数据类型转换
    表达式
    面向对象
    对齐
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290570.html
Copyright © 2020-2023  润新知