NOIP模拟 9.09

AK300分

果实计数

count.pas/.c/.cpp

时间限制:1s,空间限制32MB

题目描述:

淘淘家有棵奇怪的苹果树,这棵树共有n+1层,标号为0~n。这棵树第0层只有一个节点,为根节点。已知这棵树为b叉树,且保证是一颗满b叉树。如图为一颗满3叉树。

现在,该树第n层的每个节点上都结出了一个苹果,淘淘想知道共结了多少苹果。由于数量可能很大,答案要求输出mod k后的结果。

输入描述:

给出1的节点数b和层数nk.

输出描述:

输出苹果数mod k后的结果。

样例输入:

2 10 9

样例输出:

7

数据范围:

30%的数据保证:b<=100,n<=10, k<=100.

100%的数据保证:b<2^31,n<2^31,k<=2^15.

 【题解】

嗯?求n层完全b叉树的节点数?

嗯。。等比数列求和公式。。不对,模数是k,1-q不一定有逆元。。嗯。分治nlog^2n算法。。

嗯。。嗯?

求完全b叉树第n层节点数?

woccccccccc

这题太神辣!!

传说中的二进制拆分倍增算法啊!

(简称快速幂)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 
 6 inline void read(long long &x)
 7 {
 8     x = 0;char ch = getchar(), c = ch;
 9     while(ch < '0' || ch > '9')c = ch, ch = getchar();
10     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
11     if(c == '-')x = -x;
12 }
13 
14 long long b,n,k;
15 
16 long long pow(long long a, long long b)
17 {
18     register long long r = 1, base = a%k;
19     for(;b;b >>= 1)
20     {
21         if(b & 1)r *= base, r %= k;
22         base *= base, base %= k;
23     }
24     return r%k;
25 }
26 
27 int main()
28 {
29     read(b), read(n), read(k);
30     printf("%lld", pow(b,n)%k);
31     return 0; 
32 }
T1

打地鼠游戏

mouse.pas/.c/.cpp

时间限制:1s 空间限制:128MB

题目描述:

伟大的2320学长特别喜欢打地鼠游戏,这个游戏开始后,会在地板上冒出一些地鼠来,你可以用榔头去敲击这些地鼠,每个地鼠被敲击后,将会增加相应的游戏分值。可是,所有地鼠只会在地上出现一段时间(而且消失后再也不会出现),每个地鼠都在0时刻冒出,但停留的时间可能是不同的,而且每个地鼠被敲击后增加的游戏分值也可能是不同。

最近2320学长经常玩这个游戏,以至于敲击每个地鼠只要1秒。他在想如何敲击能使总分最大。

输入描述:

输入包含3行,第一行包含一个整数n1<=n<=100000)表示有n个地鼠从地上冒出来,第二行n个用空格分隔的整数表示每个地鼠冒出后停留的时间(Maxt<=50000),第三行n个用空格分隔的整数表示每个地鼠被敲击后会增加的分值vv<=1000)。每行中第i个数都表示第i个地鼠的信息。

样例输入:

5

5 3 6 1 4

7 9 2 1 5

样例输出:

24

数据范围:

30%的数据保证n<=100, t<=500,v<=50

60%的数据保证 n<=10000,t<=3000,v<=500

100%的数据保证 n<=100000,t<=5000,v<=1000

 【题解】

嗯。。我太弱辣,居然没有一眼看出贪心策略

把时间限制从大到小排列

从大到小扫时间

把当前时间点的地鼠压入堆

每个时间点从堆中取最大值

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <queue>
 6 #include <algorithm>
 7 #include <vector>
 8 #define max(a, b) ((a) > (b) ? (a) : (b))
 9 
10 inline void read(int &x)
11 {
12     x = 0;char ch = getchar(), c = ch;
13     while(ch < '0' || ch > '9')c = ch, ch = getchar();
14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
15     if(c == '-')x = -x;
16 }
17 
18 const int MAXN = 100000 + 10;
19 
20 int n, ma, ans;
21 
22 struct Node
23 {
24     int v,t;
25 }node[MAXN];
26 
27 bool cmp(Node a, Node b)
28 {
29     return a.t > b.t;
30 }
31 
32 struct cmpp
33 {
34     bool operator()(Node a, Node b)
35     {
36         return a.v < b.v;
37     }    
38 };
39 
40 std::priority_queue<Node, std::vector<Node>, cmpp> q;
41 
42 int main()
43 {
44     read(n);
45     for(register int i = 1;i <= n;++ i)
46         read(node[i].t), ma = max(ma, node[i].t); 
47     for(register int i = 1;i <= n;++ i)
48         read(node[i].v);
49     std::sort(node + 1, node + 1 + n, cmp);
50     register Node tmp;
51     node[n + 1].t = 0x7fffffff;
52     for(register int now = ma, i = 1;now >= 1;-- now)
53     {
54         while(node[i].t == now)
55         {
56             q.push(node[i]);
57             ++ i;
58         }
59         if(q.size())
60         {
61             tmp = q.top();
62             ans += tmp.v;
63             q.pop();
64         }
65     }
66     printf("%d", ans);
67     return 0; 
68 }
T2

斗牛

niuniu.pas/.c/.cpp)

时间限制:2s,空间限制:128MB

题目描述:

为了更快的获取欢乐豆(因为本蒟蒻斗地主水平太低233),hzwer准备去玩欢乐斗牛,但是由于rp太差,hzwer在一个小时之内输光了20QQ号的欢乐豆(每天系统会赠送每个号4000欢乐豆)。第二天他准备继续再战欢乐斗牛的抢庄模式,但是由于缺乏思考能力,hzwer需要编写一个程序来决定是否抢庄。

在玩家决定是否抢庄之前,系统会下发四张牌称为底牌,最后一张牌在决定后发放,每张牌可能为1-10JQKhzwer认为最后一张牌为每一种点数的概率是相同的,对于一个由五张牌组成的牌型,分数计算规则如下,请你得出底牌的期望得分。

首先注意:在斗牛中,JQK的点数视为10点,即111213在计算头或点数时均视为10,所有牌无视其花色。

首先考虑特殊牌型

  1. 四炸——5张牌中有4张一样的牌(33334)分数为40
  2. 五花牛——五张牌均是JQK(如JQJQK)分数为50
  3. 五小牛——五张牌点数都小于5且点数和小于或等于1011223)分数为60

若有多种特殊牌型,得分取分数最大的特殊牌型(如11112视为五小牛)。

如果没有特殊牌型,首先判断牌型是否有,如果五张牌中任意三张的总和为10的倍数如(1K9)即为有,无的牌型得分为0

对于有头的牌型得分计算如下:

所有牌的和记为t,如果t%10=0则称为牛牛”,牛牛得分为30t%10<7称为小牛,得分为t%10,否则得分为(t%10*2

输入描述:

第一行一个整数T,表示T组数据

每组数据占一行,为4个整数(111213分别表示JQK

输出描述:

对于输入的n行,输出每4张牌的期望得分(四舍五入)

样例输入:

2

2 2 2 2

10 4 5 12

样例输出:

43

9

样例解释:

对于2 2 2 2,最后一张为12时,构成五小牛,否则为炸弹,期望得分为(2*60+11*40)/13=43.08

对于10 4 5 12,最后一张为1-13的得分分别是30+0+0+0+4+5+0+0+0+18+18+18+18=111/13=8.54

1为牛牛,54点,65点,10-139点,其余无头

数据范围:

30%的数据T<=5

70%的数据T<=100000

100%的数据T<=1000000

蒟蒻感言:

在某次对局中发现期望得分很高,果断抢了庄,但是发现有闲家3牛牛,瞬间消失20W欢乐豆

【题解】

我太弱辣。。这种题居然还得调一会儿才能调对,应该是一遍过的啊

情况数*10~询问数

所以预处理所有情况即可

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #define min(a, b) ((a) < (b) ? (a) : (b))
 6 
 7 inline void read(int &x)
 8 {
 9     x = 0;char ch = getchar(), c = ch;
10     while(ch < '0' || ch > '9')c = ch, ch = getchar();
11     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
12     if(c == '-')x = -x;
13 }
14 
15 int num[6],ans[14][14][14][14][14];
16 
17 int main()
18 {
19     register int t;
20     read(t);
21     register int sum,a,b,c,d,e,ta,tb,tc,td,te;
22     for(a = 1;a <= 13;++ a)
23         for(b = 1;b <= 13;++ b)
24             for(c = 1;c <= 13;++ c)
25                 for(d = 1;d <= 13;++ d)
26                     for(e = 1;e <= 13;++ e)
27                     {
28                         if(a < 5 && b < 5 && c < 5 && d < 5 && e < 5 && a + b + c + d + e <= 10)
29                         {
30                             ans[a][b][c][d][e] = 60;
31                         }
32                         else if(a > 10 && b > 10 && c > 10 && d > 10 && e > 10)
33                         {
34                             ans[a][b][c][d][e] = 50;
35                         }
36                         else if((a == b&&b==c&&c==d) || (a==b&&b==c&&c==e) || (a==b&&b==d&&d==e) || (b==c&&c==d&&d==e) || (a==c&&c==d&&d==e))
37                         {
38                             ans[a][b][c][d][e] = 40;
39                         }
40                         else
41                         {
42                             ta = min(10, a), tb = min(10, b), tc = min(10, c), td = min(10, d), te = min(10, e);
43                             if((ta + tb + tc)%10 == 0 || (ta + tb + td)%10 == 0 || (ta + tb + te)%10 == 0 || (tb + tc + td)%10 == 0 || (tb + tc + te)%10 == 0 || (ta + tc + td)%10 == 0 || (ta + tc + te)%10 == 0 || (ta + td + te)%10 == 0 || (tb + td + te)%10 == 0 || (tc + td + te)%10 == 0)
44                             {
45                                 sum = ta + tb + tc + td + te;
46                                 if(sum%10 == 0) ans[a][b][c][d][e] = 30;
47                                 else if(sum%10 < 7)ans[a][b][c][d][e] = sum%10;
48                                 else ans[a][b][c][d][e] = (sum%10)*2;
49                             } 
50                             else
51                             {
52                                 ans[a][b][c][d][e] = 0;
53                             }
54                         }
55                     }
56     for(;t;--t)
57     {
58         read(num[1]),read(num[2]),read(num[3]),read(num[4]);
59         sum = 0;
60         for(register int i = 1;i <= 13;++ i)
61         {
62             num[5] = i;
63             sum += ans[num[1]][num[2]][num[3]][num[4]][num[5]];
64         }
65         sum = (sum/13.0) + 0.5;
66         printf("%d
", sum);
67     }
68     return 0; 
69 }
T3
原文地址:https://www.cnblogs.com/huibixiaoxing/p/7498125.html