题目链接:https://ac.nowcoder.com/acm/contest/882/A
题意
- 就是有一个含有n个节点的环,然后一个人开始在节点0,每次等概率选择向左或者向右走,问走完所有n个节点后的位置为节点m的概率,多组询问,输出前i组询问全部发生的概率
题解
- 打表找规律 233 233 233
- 打表也是一项重要的基本技能鸭~~~
打表代码
-
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int n,vis[maxn]; int solve() { memset(vis,0,sizeof(vis)); int pos=0,cnt=1;vis[0]=1; while(cnt<n){ int dir=rand()%2; pos=dir?(pos+1)%n:(pos-1+n)%n; if(!vis[pos]){ vis[pos]=1; cnt++; } } return pos; } map<int,int> cnt; int main() { while(~scanf("%d",&n)){ cnt.clear(); printf("-------------------------------%d---------------------------------------\n",n); for(int i=1;i<=1000000;i++) cnt[solve()]++; for(auto i=cnt.begin();i!=cnt.end();i++) printf("m:%d %lf\n",i->first,i->second*1.0/1000000); printf("------------------------------------------------------------------------\n"); } }
-
然后结果如下
显然答案是 1 n − 1 \frac{1}{n-1} n−11,然后特判一下 n = 1 , m = 0 n=1,m=0 n=1,m=0时答案为 1 1 1的情况就行
代码
#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
long long quick_pow(long long a,long long b)
{
long long res=1LL;
while(b){
if(b&1) res=res*a%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
int main()
{
int t,n,m;scanf("%d",&t);long long ans=1;
while(t--){
scanf("%d %d",&n,&m);
if(m==0) {
if(n==1) printf("%lld\n",ans);
else {ans=0;printf("0\n");}
}
else printf("%lld\n",ans=ans*quick_pow(n-1,mod-2)%mod);
}
}