题目: http://acm.hdu.edu.cn/showproblem.php?pid=4790
Coach Pang and Uncle Yang both love numbers. Every morning they play a game with number together. In each game the following will be done:
1. Coach Pang randomly choose a integer x in [a, b] with equal probability.
2. Uncle Yang randomly choose a integer y in [c, d] with equal probability.
3. If (x + y) mod p = m, they will go out and have a nice day together.
4. Otherwise, they will do homework that day.
For given a, b, c, d, p and m, Coach Pang wants to know the probability that they will go out.
Input
The first line of the input contains an integer T denoting the number of test cases.
For each test case, there is one line containing six integers a, b, c, d, p and m(0 <= a <= b <= 10, 0 <= c <= d <= 10, 0 <= m < p <= 10).
Output
For each test case output a single line "Case #x: y". x is the case number and y is a fraction with numerator and denominator separated by a slash ('/') as the probability that they will go out. The fraction should be presented in the simplest form (with the smallest denominator), but always with a denominator (even if it is the unit).
把可能性转化成矩形的点即可,然后取每一条可能的线求出线上的点数和就是符合条件的点。。。
细节问题要细节;
ac代码:
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <cstring>
#include <queue>
#include <iostream>
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define lc d<<1
#define rc d<<1|1
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int mx = 5e2+100;
ll a, b, c, d, m, p;
int quj(ll k) {///判断线在哪个部分
ll x = -c+m+k*p;
if (x >= a &&x <= a+d-c) return 1;
if (x <= b && x > a+d-c) return 2;
if (x > b && x <= b+d-c)
return 3;
return 0;
}
void cmp() {///交换
if (b-a+1 < d-c+1) {
swap(a, c);
swap(b, d);
}
}
void solve() {///解决问题
ll sum = 0, pp = (b-a+1)*(d-c+1);
ll k2 = (a+d-m)/p, k1 = ceil((a+c-m*1.)/p);
ll st, numk;
if (a+c < m) k1 = 0;
if (a+d < m) k2 = -1;
// printf("%lld\n", k1);
if (quj(k1) == 0) {
puts("0/1");
return;
}
if (k2 >= k1) {
numk = k2-k1;
st = -c+m+k1*p-a+1;
sum += st;
sum += numk*st+numk*(numk+1)/2*p;
k2++;
}
else k2 = k1;
// printf("1 --- %lld %lld\n", st, c);
// printf("1 --- %lld\n", sum);
if (quj(k2) == 2) {
k1 = k2;
k2 = (b+c-m)/p;
numk = k2-k1+1;
sum += numk*(d-c+1);
k2++;
}
if (quj(k2) == 3) {
k1 = k2;
k2 = (b+d-m)/p;
// printf("%lldssss \n", k2);
numk = k2-k1;
st = d-(-b+m+k2*p)+1;
sum += st;
sum += numk*st+numk*(numk+1)/2*p;
k2++;
}
// printf("2 --- %lld %lld\n", sum, pp);
printf("%lld/%lld\n", sum/__gcd(pp, sum), pp/__gcd(pp, sum));
}
int main () {
int T;
#ifndef ONLINE_JUDGE
freopen("hcl.in","r",stdin);
freopen("hcl.out","w",stdout);
#endif
scanf("%d", &T);
for (int o = 1; o <= T; ++o) {
printf("Case #%d: ", o);
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &m);
cmp();
solve();
}
return 0;
}