1. 程式人生 > >hdu 6223 Infinite Fraction Path

hdu 6223 Infinite Fraction Path

code int targe rec 堆棧 sign sca color pop

題目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6223

題意:給定長度為n的一串數字S,現在要按照一種規則尋找長度為n的數字串,使得該數字串的字典序最大。規則:從數字串S的某一個下標為x的數字出發,可以到達的下一個數字是下標為(x*x+1)%n的數字。

思路:BFS+剪枝。剪枝技巧:

1:遍歷到某一層的節點時,記錄已經到達過的節點,下次如果還經過就直接不考慮。

2:當前遍歷到的某一層節點的數字較之前的小,直接不考慮。

AC代碼:

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include
<algorithm> #include<cmath> #include<vector> #include<cstring> #include<queue> using namespace std; #define INF 0x3f3f3f3f #define EPS 1e-7 typedef unsigned long long ll; const int N_MAX = 150000+10; const int MOD = 1e10+7; int n,st[N_MAX],t;//堆棧st保存當前一層所有的節點的下標 bool vis[N_MAX];
char a[N_MAX],ans[N_MAX],_max; struct Node { int index, step; Node(int index = 0, int step = 0) :index(index), step(step) {} bool operator < (const Node &b)const { if (this->step != b.step)return step > b.step; else return a[this->index] < a[b.index]; } };
void init(int &n) { memset(st, 0, sizeof(n)); t = 0; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; i++)ans[i] = 0-1; _max = 0-1; } void bfs() { priority_queue<Node>que; for (int i = 0; i < n; i++) { if (_max == a[i]) { que.push(Node(i, 0)); }//初始將值最大的元素節點壓入隊列 } int pre_step = -1,t=0; while (!que.empty()) { Node p = que.top(); que.pop(); if (pre_step != p.step) {//判斷當前是第幾層,如果到達新一層,之前記錄銷毀 pre_step = p.step; while (t)vis[st[--t]] = false; } if (ans[p.step] > a[p.index] || p.step >= n || vis[p.index])continue;//如果當前的節點value比較小或者當前節點已經走過,剪枝 ans[p.step] = a[p.index]; st[t++] = p.index; vis[p.index] = true; que.push(Node(((ll)p.index*p.index+1)%n,p.step+1)); } } int main() { int t; scanf("%d",&t); for (int cs = 1; cs <= t;cs++) { scanf("%d", &n); init(n); scanf("%s",a); for (int i = 0; i < n;i++) _max = max(_max, a[i]); bfs(); ans[n] = \0; printf("Case #%d: %s\n",cs,ans); } return 0; }

hdu 6223 Infinite Fraction Path