训练赛后补题 02

2020-06-29 个人训练赛后补题

这题比赛上被我跳了……跳了,好的吧。

 

一开始我以为题目的意思是:小猪先拿了k个币,然后两人轮流拿一成剩下的(向下取整),我就纳闷了,向下取整到0~9个金币咋整?

然后在即将询问出题人之际脑子终于活过来:哦,是小猪每次取k,小羊每次取一成啊,得,下面是脑子活过来后写的代码:

 

Time limit exceeded on test 7

超时代码:

 1 #pragma warning (disable:4996)
 2 #include <iostream>
 3 #include<algorithm>
 4 #include<stdio.h>
 5 #include<math.h>
 6 #include<string.h>
 7 #include<string>
 8 #define MAX1 100005            /*1e5 + 5*/
 9 #define MAX2 1000000005        /*le9 + 5*/
10 #define MAX3 200005            /*1e5 + 5*/
11 #define T2 27
12 #define T3 18
13 using namespace std;
14 typedef long long int ll;
15 #define MOL 998244353
16 
17 int main() {
18     ll n, k,t,nt;
19     while (scanf("%lld", &n) != EOF) {
20         for (k = 1; k < n; ++k) {
21             nt = n;
22             t = 0;
23             while (nt > k) {
24                 nt -= k;
25                 nt -= nt / 10;
26                 t++;
27             }
28             nt += k * t;
29             if (nt >= n - nt)break;
30         }
31         printf("%lld\n", k);
32     }
33     return 0;
34 }

分析一下,时间复杂度n^2大概承受不住1e18这么大的数据

然后又发现实际上每个k对应n有一定的范围,要是硬应付timelimit暴力撞库不是不可以……

但是毕竟是补题。

化简思路:k从大入手不划算,从小入手复杂度太大,那就从中间;取中间值,k使小猪胜利就继续取前区间中值,不能就取后区间中值。

最终AC代码:

 1 #pragma warning (disable:4996)
 2 #include <iostream>
 3 #include<algorithm>
 4 #include<stdio.h>
 5 #include<math.h>
 6 #include<string.h>
 7 #include<string>
 8 #define MAX1 100005            /*1e5 + 5*/
 9 #define MAX2 1000000005        /*le9 + 5*/
10 #define MAX3 200005            /*1e5 + 5*/
11 #define T2 27
12 #define T3 18
13 using namespace std;
14 typedef long long int ll;
15 #define MOL 998244353
16 
17 int ispig_wim(ll n, ll k) {
18     ll t = 0;
19     ll nt = n;
20     while (nt > k) {
21         nt -= k;
22         nt -= nt / 10;
23         t++;
24     }
25     nt += k * t;
26     if (nt >= n - nt)return 1;
27     return 0;
28 }
29 int main() {
30     ll n, k;
31     while (scanf("%lld", &n) != EOF) {
32         ll low = 1, high = n, mid = (low + high) / 2;
33         while (low < high) {
34             if (ispig_wim(n, mid))
35                 high = mid;
36             else
37                 low = mid + 1;
38             mid = (high + low) / 2;
39         }
40         k = mid;
41         printf("%lld\n", k);
42     }
43     return 0;
44 }

我不该跳过这一题的,别问,问就是后悔

posted @ 2020-06-30 13:59  听说福建人很好吃  阅读(92)  评论(0)    收藏  举报