题意:n 个点,标号为 0~(n-1),每个点有一个 0~9 的数字权值,第 i 个点只能走到标号为 (i*i+1)%n 的点。从每个点出发走 n 步,n 个点权可以组合成一个数,求出可能的最大的那个数。
tags: 好玄学的题。。。 T到死。
1】 bfs ,每一步选最大的数字,再加一些迷之剪枝就过了。。 但仔细想想其实这样写复杂度也有点问题。。。
2】 据说沈阳比赛的时候,可以对每个点预处理出 sqrt(n) 个后继点,然后暴力搞。 但我这样拍了一下,不知道是写挫了还是加了数据,一直 T。。。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second #define max(a, b) ((a>b) ? a : b) typedef long long ll; const int N = 150005; int T, n, vis[N]; char D[N], ans[N]; struct Node { int skip; char pi; ll pos; bool friend operator < (Node a, Node b) { if(a.skip==b.skip) return a.pi < b.pi; return a.skip > b.skip; } }; priority_queue<Node > q; int main() { scanf("%d", &T); rep(cas, 1, T) { scanf("%d%s", &n, D); char mx = '0'; rep(i,0,n-1) mx = max(mx, D[i]), ans[i]='0'; rep(i,0,n-1) if(D[i]==mx) q.push((Node){0, D[i], i}); mes(vis, -1); ll pos; int id; while(!q.empty()) { Node u = q.top(); q.pop(); id = u.skip; if(ans[id] > u.pi) continue; ans[id] = max(ans[id], u.pi); if(vis[u.pos] >= id) continue; vis[u.pos] = max(vis[u.pos], id); if(id == n-1) continue; pos = (u.pos*u.pos+1)%n; q.push( (Node){id+1, D[pos], pos} ); } printf("Case #%d: ", cas); rep(i,0,n-1) putchar(ans[i]); puts(""); } return 0; }