当前位置 : 主页 > 网络推广 > seo >

WXH的路径

来源:互联网 收集:自由互联 发布时间:2021-06-16
WXH的路径 思路: 走到每一步有许多选择,每种选择划出了一个区间,判断k在那个区间内,模拟向前走 #include iostream #include cstdio #include algorithm #include cstring #include queue #include vector #in

WXH的路径

思路:
走到每一步有许多选择,每种选择划出了一个区间,判断k在那个区间内,模拟向前走

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#define LL long long
#define N 1000010
#define mod 1000000000000000007LL
#define pr pair<char, int>
using namespace std;

LL x, y, k, cnt=0, f[N], vis[N], n, m, nxt[N];
char s[N], pos[N];
priority_queue < pr, vector<pr>, greater<pr> > q;

inline LL up( LL a, LL b ) {//没有模数只有边界的做法 
    LL c = a + b;
    if( c > mod ) c = mod;
    return c;
}

inline LL chen( LL a, LL b ) {//判位数 
    if((int)log((double)a) + (int)log((double)b) > (int)log((double)mod)) return mod;
    return a * b;
}

void init(){//预处理方案数 
    for(int i=n; i>=1; i--){
        for(int j=m; j>=1; j--){
            if(i==n && j==m) f[(i-1)*m+j] = 1;
            else {
                if(j != m) f[(i-1)*m+j] = f[(i-1)*m+j+1];
                if(i != n) f[(i-1)*m+j] = up(f[i*m+j], f[(i-1)*m+j]);
            }
        }
    }
}

inline void add(int x, LL tim){
    if((x - 1) / m < n - 1 && !vis[x + m])  q.push( make_pair(pos[x + m], x + m) );
    vis[x + m] = up(vis[x + m], tim);
    if(x - (x - 1) / m * m < m && !vis[x + 1])  q.push( make_pair(pos[x + 1], x + 1) );
    vis[x + 1] = up(vis[x + 1], tim);
}

int main(){
    freopen ("path.in", "r", stdin);
    freopen ("path.out", "w", stdout);
    scanf("%lld%lld", &n, &m);
    init();
    for(int i=1; i<=n; i++){
        scanf("%s", s+1);
        for(int j=1; j<=m; j++){
            pos[(i-1)*m+j] = s[j];
        }
    }
    cin >> k;
    q.push( make_pair(pos[1], 1) );
    vis[1] = 1;
    LL sum = 0, psum = 0; int pre = 0, now; char ch;
    if ( f[1] < k ){
        printf("Impossible\n");
        return 0;
    }
    while ( !q.empty() ){
        now = q.top().second;
        nxt[now] = pre; ch = pos[now];
        sum = up( sum, chen(f[now], vis[now]) );
        q.pop();
        pre = now;
        if(!q.empty() && q.top().first == ch) continue;
        if(sum >= k){
            while ( !q.empty() ) q.pop();
            add(now, vis[now]);
            while ( pos[nxt[now]] == ch ) { 
                now = nxt[now]; 
                add(now, vis[now]);
            }
            k -= psum;
            printf("%c", ch); cnt++;
            sum = 0; pre = 0;
            psum = 0;
        }
        else psum = sum;
    }
}
网友评论