HDU - 6229 Wandering Robots

传送门:点击打开链接

题意:有一个n*n的区域,左上角坐标为(0,0),在左上角有一个机器人,他每次留在原地和前往其他可前往的格子的概率相等,最后若干时间之后,求机器人最后在(x,y)(x+y>=n-1)的点的概率是多少。

分析: 给每个点赋一个权值,权值的大小就代表当前点可以被几个点所到达(包括自身),4个角落的点的权值为3,边缘除角落的权值为4,其余点权值为5,分母就是所有点的权值和,分子是所有终点的权值和。因为n=10000,所以不能暴力,但是因为障碍最多只有1000个,所以我们可以用map或者set把所有的障碍事先存起来。之后对于这些点枚举,用总贡献减去这些点的贡献即可。注意可以需要注意障碍点到达障碍点不需要减,我们需要set标记判断。注意n=1特判。

补充:C++中,结构体是无法进行==,>,<,>=,<=,!=,需要重载,=不需要重载,set内部元素会自动排序,所以set<结构体>需要重载<。

我的代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 1e4+10;
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define eps 1e-10
ll t,n,k,fz,fm;
int to[4][2]={-1,0,1,0,0,-1,0,1};

struct br{
    ll x,y;
    bool operator==(const br &a) {///重载==
        return (x==a.x)&&(y==a.y);
    }
    bool operator < (const br a) const {///重载<
        if(x==a.x) return y st;

ll gcd(ll a,ll b) {
    if(b==0) return a;
    else return gcd(b,a%b);
}

ll gv(ll x,ll y) {
    ll s=5;
    if(x==0||x==n-1) s--;
    if(y==0||y==n-1) s--;
    return s;
}

void sv() {
    fz=9+8*(n-2)+5*(n-1)*(n-2)/2;
    fm=12+16*(n-2)+5*(n-2)*(n-2);
    for(int i=0;i=n-1) fz-=gv(b[i].x,b[i].y);
        for(int j=0;j<4;j++) {
            ll xx=b[i].x+to[j][0],yy=b[i].y+to[j][1];
            if(xx<0||xx>=n||yy<0||yy>=n||st.count({xx,yy})) continue;
            fm--;
            if(xx+yy>=n-1) fz--;
        }
    }
    ll tp=gcd(fz,fm);
    fz/=tp,fm/=tp;
    cout<>t;
    for(int l=1;l<=t;l++){
        cin>>n>>k;
        for(int i=0;i>b[i].x>>b[i].y,st.insert({b[i].x,b[i].y});
        cout<<"Case #"<

参考代码:

#include  
using namespace std;  
typedef long long ll;  
const int maxn=2e5+5;  
int dx[4]={0,1,0,-1};  
int dy[4]={1,0,-1,0};  
int n,m,p,q;  
map,int> ma;  
int check(int x,int y)  //判断当前点的贡献  
{  
    if((x==0||x==n-1)&&(y==0||y==n-1))  return 3;  
    if((x==0||x==n-1)&&(y!=0&&y!=n-1))  return 4;  
    if((y==0||y==n-1)&&(x!=0&&x!=n-1))  return 4;  
    return 5;  
}  
int main()  
{  
    int QAQ,kase=0;  
    scanf("%d",&QAQ);  
    while(QAQ--)  
    {  
        ma.clear();p=0,q=0;  
        scanf("%d%d",&n,&m);  
        while(m--)  
        {  
            int x,y;  
            scanf("%d%d",&x,&y);  
            ma[make_pair(x,y)]=1;  
        }  
        if(n==1)    //n==1 特判  
        {  
            if(m==1) printf("0\n");  
            else printf("1");  
        }  
        else  
        {  
            q+=((3*4)+((n-2)*4*4)+(n-2)*(n-2)*5);   //分母  
            p+=((3*3)+((n-2)*2*4)+((n-2)*(n-1)/2*5));   //分子  
            for(auto it=ma.begin();it!=ma.end();it++)   //遍历所有障碍  
            {  
                int x=it->first.first;  
                int y=it->first.second;  
                q-=check(x,y);  //减去对分母的贡献  
                if(x+y>=n-1) p-=check(x,y);     //减去对分子的贡献  
                for(int i=0;i<4;i++)    //判断对周围点的贡献的影响  
                {  
                    int xx=x+dx[i];  
                    int yy=y+dy[i];  
                    if(xx>=0&&xx=0&&yy=n-1) p--;  
                        q--;  
                    }  
                }  
            }  
            int gk=__gcd(p,q);  //化简  
            printf("Case #%d: %d/%d\n",++kase,p/gk,q/gk);  
        }  
    }  
    system("pause");  
} 

你可能感兴趣的:(ACM)