2015百度之星资格赛题解

题目链接: http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=584

A.

思路:题目可以看成这样一个模型,把n个物品分成若干组,使得每组只有1个或两个物品的方法总数。令dp[n]表示n个物品的答案,则有:

dp[n] = dp[n-1] + (n - 1) * dp[n - 2]

代码如下: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 1e6 + 7;
const int md = 1000000007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
int ans[maxn];
 
void init() {
    ans[1] = 1;
    ans[2] = 2;
    for (int i = 3; i <= 1000000; i ++) {
        ans[i] = (ans[i - 1] + (LL)(i - 1) * ans[i - 2]) % md;
    }
}
 
int main() {
    //freopen("in.txt", "r", stdin);
    init();
    int T, n;
    cin >> T;
    rep_up1(cas, T) {
        cin >> n;
        printf("Case #%d:\n%d\n", cas, ans[n]);
    }
    return 0;
}

 

B.

思路:直接还原原矩阵或者找输入输出的对应关系即可 。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 120000;
const int md = 1000000007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
vector<vector<char> > ch;
char s[maxn];
 
int main() {
    //freopen("in.txt", "r", stdin);
    int T, k;
    cin >> T;
    scanf("%*c");
    rep_up1(cas, T) {
        gets(s);
        scanf("%d%*c", &k);
        printf("Case #%d:\n", cas);
        int n = strlen(s);
        ch.resize(n / k + 2);
        rep_up0(i, n / k + 2) ch[i].resize(k);
        int cur = 0;
        rep_up0(i, n % k) {
            rep_up0(j, n / k + 1) {
                ch[j][i] = s[cur ++];
            }
        }
        for (int i = n % k; i < k; i ++) {
            rep_up0(j, n / k) {
                ch[j][i] = s[cur ++];
            }
        }
        rep_up0(i, n / k) {
            rep_up0(j, k) {
                pchr(ch[i][j]);
            }
        }
        rep_up0(i, n % k) {
            pchr(ch[n / k][i]);
        }
        cout << endl;
    }
    return 0;
}

 

C.

思路:二进制运算和map判重。

代码如下: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 120000;
const int md = 1000000007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
map<uint, bool> mp;
uint a[1010];
 
int main() {
    //freopen("in.txt", "r", stdin);
    int T, w, x, y, z, n, m;
    cin >> T;
    rep_up1(cas, T) {
        printf("Case #%d:\n", cas);
        cin >> n >> m;
        rep_up0(i, n) {
            scanf("%d.%d.%d.%d", &w, &x, &y, &z);
            a[i] = (uint)w << 24 | x << 16 | y << 8 | z;
        }
        rep_up0(i, m) {
            scanf("%d.%d.%d.%d", &w, &x, &y, &z);
            uint p = (uint)w << 24 | x << 16 | y << 8 | z;
            mp.clear();
            int ans = 0;
            rep_up0(i, n) {
                uint res = p & a[i];
                if (!mp[res]) {
                    ans ++;
                    mp[res] = 1;
                }
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

 

D.

思路:只要先手可以走第一步,那么它一定会走完最后一步,因为之后只需走后手的对称位置。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 120000;
const int md = 1000000007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
 
int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    cin >> T;
    rep_up1(cas, T) {
        printf("Case #%d:\n", cas);
        double n, a, r;
        cin >> n >> a >> r;
        puts(a / 2 * tan((n - 2) / n * pi / 2) >= r? "Give me a kiss!" "I want to kiss you!");
    }
    return 0;
}

 

e.

思路:对于某个点,如果骑士能在时刻t到达,那么它也能在t+2,t+4,t+6...的时刻到达,如果国王能在时刻t到达,那么它能在之后的每个时刻到达。当然起始位置需要另外考虑。bfs求出骑士到达每个格子的最早时刻,国王到达这个格子的最早时刻可以直接根据坐标计算出来(max(abs(x-x0),abs(y-y0))),然后相当于求出了骑士和格子到达这个点的所有时刻了,用最早的相遇时刻更新答案即可)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 120000;
const int md = 1000000007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
const int xma[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
const int yma[8] = {1, 2, 2, 1, -1, -2, -2, -1};
struct Node {
    int x, y, dep;
    constructInt3(Node, x, y, dep);
};
bool mark[1010][1010];
 
int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    cin >> T;
    rep_up1(cas, T) {
        printf("Case #%d:\n", cas);
        int n, m, k, x1, y1, x2, y2;
        cin >> n >> m >> k;
        cin >> x1 >> y1 >> x2 >> y2;
        x1 --; y1 --; x2 --; y2 --;
        queue<Node> Q;
        Q.push(Node(x2, y2, 0));
        mem0(mark);
        mark[x2][y2] = true;
        bool ok = false;
        int ans = inf;
        while (!Q.empty()) {
            Node H = Q.front(); Q.pop();
            int cost2 = max(abs(H.x - x1), abs(H.y - y1));
            if (cost2 == 0) cost2 = 2;
            if (cost2 <= H.dep) min_update(ans, H.dep);
            else {
                int p0 = cost2 & 1, p1 = H.dep & 1;
                if (p0 ^ p1) {
                    if (cost2 + 1 <= k) min_update(ans, cost2 + 1);
                }
                else {
                    if (cost2 <= k) min_update(ans, cost2);
                }
            }
            if (H.dep == k) continue;
            rep_up0(i, 8) {
                int x = H.x + xma[i], y = H.y + yma[i];
                if (x >= 0 && x < n && y >= 0 && y < m && !mark[x][y]) {
                    mark[x][y] = true;
                    Q.push(Node(x, y, H.dep + 1));
                }
            }
        }
        if (ans == inf) puts("OH,NO!");
        else cout << ans << endl;
    }
    return 0;
}

 

f.

思路:这居然是个O(1)的数学题=.=我尝试性地用DP做了一下,跑得太慢,由于各种除法也有一点精度问题,不过后来改用long double存,和标准程序把所有程序对拍了一下还是通过了。

详细分析见matrix67的博客:http://www.matrix67.com/blog/archives/5296

AC代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 1e3 + 7;
const int md = 1e9 + 9;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
 
 
 
int main() {
    //freopen("in.txt", "r", stdin);
    int T, cas = 0;
    double n;
    cin >> T;
    while (T --) {
        printf("Case #%d:\n", ++ cas);
        cin >> n;
        if (n == 1) {
            puts("0.000000 1.000000");
            continue;
        }
        printf("%.6f %.6f\n", 1 + (n - 2) * 19.0 / 27, (46 - 38.0/n) / (19 - 11.0/n));
    }
    return 0;
}

离线通过的DP:

dp[i][j]表示长度为i第一位为j的先上升序列的平均单调区间数,dp2[i][j]表示相应的平均单调区间长度,状态方程不难想出来,注意先上升序列以j开头与先下降序列以9-j开头这个状态是等价的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#pragma comment(linker, "/STACK:10240000,10240000")
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
#include <iomanip>
 
using namespace std;
 
#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
 
typedef unsigned int uint;
typedef long long LL;
typedef pair<intint> pii;
typedef vector<int> vi;
 
const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 1e5 + 7;
const int md = 998244353;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
 
template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }
 
long double dp[maxn][10], dp2[maxn][10];
LL c[12][12];
LL u9[10] = {1, 9, 81, 81 * 9, 81 * 81, 81 * 81 * 9, 81 * 81 * 81, 81 * 81 * 81 * 9, 81 * 81 * 81 * 81, 81 * 81 * 81 * 81 * 9};
void init() {
    c[0][0] = 1;
    rep_up1(i, 9) {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j < i; j ++) {
            c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
        }
    }
    for (int i = 2; i <= 100000; i ++) {
        rep_up0(j, 9) {
            rep_up1(k, 9 - j) {
                if (i - k < 1) break;
                for (int p = j + k; p <= 9; p ++) {
                    double buf = (dp[i - k][9 - p] + 1) * c[p - j - 1][k - 1];
                    if (i - k - 2 < 0) {
                        buf /= 9 - j;
                        buf /= u9[i - 2];
                    }
                    else {
                        buf *= (double)p / (9 - j);
                        buf /= u9[k];
                    }
                    dp[i][j] += buf;
 
                }
            }
            rep_up1(k, 9 - j) {
                if (i - k < 1) break;
                for (int p = j + k; p <= 9; p ++) {
                    double buf = (dp2[i - k][9 - p] * dp[i - k][9 - p] + k) * c[p - j - 1][k - 1]  / dp[i][j];
                    if (i - k - 2 < 0) {
                        buf /= 9 - j;
                        buf /= u9[i - 2];
                    }
                    else {
                        buf *= (double)p / (9 - j);
                        buf /= u9[k];
                    }
                    dp2[i][j] += buf;
                }
            }
        }
    }
}
 
 
int main() {
    //freopen("in.txt", "r", stdin);
    init();
    int T, cas = 0, n;
    cin >> T;
    while (T --) {
        printf("Case #%d:\n", ++ cas);
        cin >> n;
        if (n == 1) {
            puts("0.000000 1.000000");
            continue;
        }
        long double ans = 0, ans2 = 0, sum = 0;
        rep_up0(i, 9) ans += dp[n][i] * (9 - i) / 45;
        rep_up0(i, 9) sum += dp[n][i] * (9 - i);
        rep_up0(i, 9) ans2 += dp2[n][i] * dp[n][i] * (9 - i);
        cout.precision(6);
        cout << fixed << ans << " " << 1.0 + ans2 / sum << endl;
    }
    return 0;
}

 

 

posted @ 2015-05-29 01:17  jklongint  阅读(224)  评论(0编辑  收藏  举报