题意:有三个杯子,其中一个里面有一枚硬币,每次可以左边或右边的杯子和中间的杯子交换,问进行了n次操作后,中间有硬币的概率是多少。
分析:在纸上写写每一次左、中、右拥有硬币的概率,写到7或8大概就能看出规律了。
一开始找到的通式是:f(n)=(f(n-1)+f(n-2))/2, 然后经过转换编程f(n)=(1-f(n-1))/2,然后再转换变成f(n)=an/bn的形式。
然后看规律又可以看出bn=2^(n-1),
当n为奇数时:a=(2^(n-1)-1)/3,
当n为偶数时:a=(2^(n-1)-2)/3+1.
/************************************************ Author :DarkTong Created Time :2016/7/15 19:27:41 File Name :E.cpp *************************************************/ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> #define INF 0x3f3f3f3f #define esp 1e-9 typedef long long LL; using namespace std; const int MOD = 1e9+7; const int maxn = 100000 + 100; LL aa[maxn]; LL quick_mod(LL t,LL n) { LL ans=1; while(n) { if(n&1) ans=ans*t%MOD; t=t*t%MOD; n>>=1; } return ans; } LL Inv(LL x) { return quick_mod(x, MOD-2); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); LL inv3 = Inv(3); LL inv2 = Inv(2); int n, f=1, f2=0; scanf("%d", &n); for(int i=1;i<=n;++i) { scanf("%lld", &aa[i]); if(aa[i]%2==0) f=0; if(aa[i]>1) f2=1; } if(!f2) { puts("0/1"); return 0; } LL b=1, a=1; b=quick_mod(2, aa[1]); for(int i=2;i<=n;++i) { b=quick_mod(b, aa[i]); } b=b*inv2%MOD; if(f) { a=((b-1+MOD)*inv3%MOD); } else { a=((b-2+MOD)*inv3%MOD+1)%MOD; } printf("%lld/%lld\n", a, b); return 0; }
时间: 2024-10-05 12:36:08