HDU 3031 ToBe Or Not To Be(模拟)

这篇博客介绍了一个两人轮流抓牌的游戏,操作牌共有五种,目标是通过模拟游戏过程,判断最终谁手中的牌多。作者分享了自己用水桶队列(priority_queue)解决这个问题的思路和代码实现,尽管问题的本质是左偏树(leftist tree)问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给你一堆牌,再给你5种操作牌,两个人轮流抓操作牌,并且按照操作来执行,最后谁手里的牌多谁就赢。
明明是左偏树的题目,但是我用priority_queue水过去了。。。

代码:

#include <queue>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

#define N 200 + 5

using namespace std;

typedef struct
{
   int num ,v;
   double x ,y ,z;
}NODE;

typedef struct
{
   double dis;
   int v ,id;
}ZT;

NODE node1[N] ,node2[N];
ZT zt[N];
int map[N][N] ,G_b[N][N];
int nowb[N] ,nowg[N];
int mark[N][N];

bool camp(ZT a ,ZT b)
{
   return a.dis < b.dis || a.dis == b.dis && a.v > b.v;
}

void Marr(int n)
{
   queue<int>q;
   for(int i = 1 ;i <= n ;i ++)
   q.push(i);
   memset(mark ,0 ,sizeof(mark));
   memset(nowb ,255 ,sizeof(nowb));
   memset(nowg ,255 ,sizeof(nowg));
   while(!q.empty())
   {
      int xin ,tou = q.front();
      q.pop();
      for(int i = 1 ;i <= n ;i ++)
      {
         xin = map[tou][i];
         if(mark[tou][xin]) continue;
         mark[tou][xin] = 1;
         if(nowg[xin] == -1)
         {
            nowg[xin] = tou;
            nowb[tou] = xin;
            break;
         }
         else
         {
            if(G_b[xin][tou] > G_b[xin][nowg[xin]])
            {
               q.push(nowg[xin]);
               nowg[xin] = tou;
               nowb[tou] = xin;
               break;
            }
         }
      }
   }
   return;
}

double get_dis(NODE a ,NODE b)
{
   double xx = (a.x - b.x) * (a.x - b.x);
   double yy = (a.y - b.y) * (a.y - b.y);
   double zz = (a.z - b.z) * (a.z - b.z);
   return xx + yy + zz;
}


int main ()
{
#ifdef LOCAL
    freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin);
    // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout);
#endif
   int t ,n ,i ,j;
   scanf("%d" ,&t);
   while(t--)
   {
      scanf("%d" ,&n);
      for(i = 1 ;i <= n ;i ++)
      scanf("%d %d %lf %lf %lf" ,&node1[i].num ,&node1[i].v ,&node1[i].x ,&node1[i].y ,&node1[i].z);
      for(i = 1 ;i <= n ;i ++)
      scanf("%d %d %lf %lf %lf" ,&node2[i].num ,&node2[i].v ,&node2[i].x ,&node2[i].y ,&node2[i].z);
      for(i = 1 ;i <= n ;i ++)
      {
         for(j = 1 ;j <= n ;j ++)
         {
            zt[j].dis = get_dis(node1[i] ,node2[j]);
            zt[j].v = node2[j].v;
            zt[j].id = j;
            // cout << zt[j].dis << endl;
         }
         sort(zt + 1 ,zt + n + 1 ,camp);
         for(j = 1 ;j <= n ;j ++)
         map[i][j] = zt[j].id;
      }
      // for (int i=1;i <= n; i++) {
      //    for (int j = 1; j <= n; j++) cout << map[i][j] << ' ';
      //    cout << endl;
      // }
      for(i = 1 ;i <= n ;i ++)
      {
         for(j = 1 ;j <= n ;j ++)
         {
            zt[j].dis = get_dis(node2[i] ,node1[j]);
            // cout << node1[j].num << ' ' << node1[j].v << ' ' << node1[j].x << ' ' << node1[j].y << ' ' << node1[j].z << endl;
           // cout << zt[j].dis << endl;
           zt[j].v = node1[j].v;
            zt[j].id = j;
         }
         sort(zt + 1 ,zt + n + 1 ,camp);
         for(j = 1 ;j <= n ;j ++)
         G_b[i][zt[j].id] = n - j + 1;
      }
      // for (int i = 1; i <= n; i++) {
      //    for (int j = 1; j <= n; j++) cout << G_b[i][j] << ' ' ;
      //        cout << endl;
      // }
      Marr(n);
      for(i = 1 ;i <= n ;i ++)
      printf("%d %d\n" ,node1[i].num ,node2[nowb[i]].num);
      puts("");
   }
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值