hdu 6229

(找规律)
题意:题目共 T(T103) 组数据,每组数据里给定一个 n×n(n104) 的格子,其中有 k(k103) 个格子里面有障碍物。先将一个机器人放在 (0,0) 处,它只能向上下左右原地五个方向移动(不能移动到障碍物上),假设能移动的位置有 d 个,那么它移动到每个位置的概率就是 1d+1 ,然后很久很久之后,求它到达方格子右下半部分的概率。

思路:(直接根据样例找规律)依次统计能向 i(i[1,5]) 个位置移动的点有多少个,记为 cnti ,然后 5i=1cnti 就是总数了,然后再求出右下半部分的数,然后一除就是所求概率。

代码:

#include <cstdio>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>
#define LL long long

using namespace std;
const int maxm = 10010;

struct node {
    int x, y;
    node(int a=0, int b=0):x(a),y(b){}
    bool operator < (const node &A) const {
        return y < A.y || (y == A.y && x < A.x);
    }
};

LL nume, deno, N, K;
void init() {
    if(N == 1) {
        nume = deno = 1;
    }
    else if(N == 2) {
        nume = 9; deno = 12;
    }
    else {
        nume = (LL)5*(N-2)*(N-1)/2 + (LL)4*2*(N-2) + (LL)3*3;
        deno = (LL)5*(N-2)*(N-2) + (LL)4*4*(N-2) + (LL)3*4;
    }
}

set<node> barrier, lattice;
set<node>::iterator iter;
const int dx[] = {0, 0, 1, -1, 0};
const int dy[] = {1, -1, 0, 0, 0};
bool valid(node cur) {
    int x = cur.x, y = cur.y;
    if(0 <= x && x < N && 0 <= y && y < N) return true;
    return false;
}

void make_change(node cur, LL val) {
    int x = cur.x, y = cur.y;
    if(val == -1) {
        if(N == 1) val = -1;
        else if(N == 2) val = -3;
        else {
            if(0 < x && x < N-1 && 0 < y && y < N-1)
                val = -5;
            else if((x==0&&y==0)||(x==0&&y==N-1)||(x==N-1&&y==0)||(x==N-1&&y==N-1))
                val = -3;
            else val = -4;
        }
    }
    if(x + y >= N-1) nume += val;
    deno += val;
}
LL gcd(LL a, LL b){ return a == 0 ? b : gcd(b % a, a); }

void solve(int cas) {
    nume = deno = 0;
    scanf("%I64d%I64d",&N,&K);
    init();
    //printf("%I64d %I64d\n",nume,deno);
    barrier.clear(); lattice.clear();
    for(int i=0; i<K; i++) {
        int x, y;
        scanf("%d%d",&x,&y);
        barrier.insert(node(x, y));
    }
    for(iter=barrier.begin(); iter!=barrier.end(); iter++) {
        node bar = *iter;
        for(int i=0; i<5; i++) {
            int nowx = bar.x + dx[i], nowy = bar.y + dy[i];
            node cur = node(nowx, nowy);
            if(valid(cur) && lattice.find(cur)==lattice.end()) {
                lattice.insert(cur);
                //printf("cur: %d %d\n",cur.x,cur.y);
                make_change(cur, -1);
                //printf("before : %I64d %I64d\n",nume,deno);
                if(i == 4 || barrier.find(cur) != barrier.end()) continue ;
                LL adj = 1;
                for(int j=0; j<4; j++) {
                    int ad_x = cur.x + dx[j], ad_y = cur.y + dy[j];
                    node ad_node = node(ad_x, ad_y);
                    if(!valid(ad_node) || barrier.find(ad_node)!=barrier.end()) continue ;
                    adj ++;
                }
                make_change(cur, adj);
                //printf("after : %I64d %I64d\n",nume,deno);
            }
        }
    }
    LL gg = gcd(nume, deno);
    printf("Case #%d: %I64d/%I64d\n",cas,nume/gg,deno/gg);
}

int main() {
    int T;
    scanf("%d",&T);
    for(int i=1; i<=T; i++)
        solve(i);
    return 0;
}
发布了40 篇原创文章 · 获赞 44 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Site1997/article/details/78804975