【题解+代码】HDU6223 Infinite Fraction Path

Infinite Fraction Path

优先队列BFS + 剪枝
思路都在注释里

参考题解 CSDN
题目链接

// reference: https://www.cnblogs.com/stranger-/p/7841085.html
// BFS + 剪枝,略抽象

#include <bits/stdc++.h>
#define MAX 150005

using namespace std;

int n, m; // n是题目里的N
int dst[MAX]; // 每个城市的终点
int val[MAX]; // 每个城市对应的0-9的数字
int vis[MAX]; // 记录每个点被访问的情况
int ans[MAX]; // 记录答案
char str[MAX];

struct node
{
   int val, pos, ans; // val数组中对应的值,下标,ans数组的下标

   node(int val, int pos, int ans)
   {
       this->val = val;
       this->pos = pos;
       this->ans = ans;
   }

   friend bool operator<(node n1, node n2)
   {
       if (n1.ans != n2.ans)
           return n1.ans > n2.ans;
       if (n1.val != n2.val)
           return n1.val < n2.val;
       else
           return n1.pos > n2.pos;
   }
};

int main()
{
   cin.sync_with_stdio(false);
   cin.tie(0); // 不一定要关流

   int cases;
   cin >> cases;

   for (int caseCount = 1; caseCount <= cases; ++caseCount)
   {
       cin >> n;
       cin >> str;
       m = 0;

       for (long long i = 0; i < n; ++i)
       {
           val[i] = str[i] - '0';
           dst[i] = int((i * i + 1) % n); // n最大是150000,平方会爆int,所以i用long long
           vis[i] = ans[i] = -1;
           m = max(m, val[i]);
       }

       priority_queue <node> q;
       for (int i = 0; i < n; ++i)
       {
           if (val[i] == m)
               q.push(node { m, i, 0 });
       }

       while (!q.empty())
       {
           node now = q.top();
           q.pop();

           if (ans[now.ans] == -1) // 该位置未赋值,赋初值
               ans[now.ans] = now.val; // 由于优先队列的排序,所有ans相同的node中,排在最前面的是val最大的,所以只需要
                                       // 一次赋值,剩下的情况都从下面的那个if那里略去了

           if (ans[now.ans] > now.val) // 剪枝:已经出现了比当前情况大的情况
               continue;

           if (vis[now.pos] < now.ans)
               vis[now.pos] = now.ans;
           else
               continue; // 剪枝:当前节点已经被具有相同ans值的其他分支访问过了,后续的结果都是相同的,不重复访问
                         // 因为ans值小的node在priority_queue中排在前面,不会出现vis[now.pos] > now.ans的情况

           if (now.ans == n - 1)
               continue; // 已经得出答案

           q.push(node { val[dst[now.pos]], dst[now.pos], now.ans + 1 });
       }

       cout << "Case #" << caseCount << ": ";
       for (int i = 0; i < n; ++i)
           cout << ans[i];
       cout << endl;
   }
}

猜你喜欢

转载自blog.csdn.net/weixin_41429999/article/details/85347002