传送门:点击打开链接
题意:有一个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
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");
}