BestCoder Round #11 题解集合

1001.Alice and Bob

签到题*1,只要x * 2 == n && y * 2 == m就满足条件。

1 var
2   m, n, x, y : int64;
3   
4 begin
5   while not eof do begin
6     readln(m, n, x, y);
7     if (m = 2 * x) and (n = 2 * y) then writeln('YES') else writeln('NO');
8   end;
9 end.
View Code

1002.Bob and math problem

我真是WA的不行,但是很明显我的算法没有问题啊。。。

(2014/9/28 22:36更新 原来是Pascal的eof做的死,早知道以后不再也用P了><)

我的算法:统计0到9的个数,然后找出最小的奇数放到末尾,接着从9到0输出,最后输出选出的那个奇数。

中间要判断输出-1的情况:没有奇数;找出一个奇数以后只剩下0了。

 1 var
 2   num : array[0..9] of longint;
 3   n, ch, i, j, x : longint;
 4 
 5 function find : boolean;
 6 var
 7   i : longint;
 8   flag : boolean;
 9 
10 begin
11   flag := true;
12   for i := 1 to 9 do
13     if num[i] > 0 then flag := false;
14   find := flag and (n <> 1);
15 end;
16 
17 begin
18   while not eof do begin
19     readln(n);
20     if n = 0 then exit;//这句话没加我就会WA,不知道为啥子捏~
21     fillchar(num, sizeof(num), 0);
22     for i := 1 to n do begin
23       read(x);
24       inc(num[x]);
25     end;
26     ch := 0;
27     for i := 1 to 5 do begin
28       j := i * 2 - 1;
29       if num[j] > 0 then begin
30         ch := j;
31         dec(num[j]);
32         break;
33       end;
34     end;
35     if (ch = 0) or find then begin
36       writeln(-1);
37       continue;
38     end;
39     for i := 9 downto 0 do
40       while num[i] > 0 do begin
41         write(i);
42         dec(num[i]);
43       end;
44     writeln(ch);
45   end;
46 end.
View Code

1003.Boring count

这道题看了数据范围就知道要O(n)的算法,因为O(nlogn)的算法有点不大科学。。。

于是我来统计以每个字符s[j]为结尾的满足要求的字符串的个数,不妨设suff[i, j]表示s[i]到s[j]的子串。

又很明显如果suff[i, j]不满足条件了,则suff[i - 1, j]也不满足条件,若令f[j]表示以字符s[j]结尾的最左边满足条件的位置,则f[j]关于j是单调增的。

于是每次枚举j然后查找f[j], ans += j - f[j] +1即可。

 1 var
 2   i, x, k, len, left, t1 : longint;
 3   first, next, num, last : array[0..150000] of longint;
 4   s : ansistring;
 5   T : longint;
 6   ans : int64;
 7 
 8 begin
 9   readln(T);
10   while T > 0 do begin
11     dec(T);
12     ans := 0;
13     readln(s);
14     readln(k);
15     len := length(s);
16     left := 0;
17     fillchar(first, sizeof(first), 0);
18     fillchar(last, sizeof(last), 0);
19     fillchar(num, sizeof(num), 0);
20 
21     for i := 1 to len do begin
22       x := ord(s[i]);
23       if first[x] = 0 then first[x] := i;
24       inc(num[x]);
25       next[last[x]] := i;
26       last[x] := i;
27       if num[x] > k then begin
28         dec(num[x]);
29         t1 := first[x];
30         first[x] := next[first[x]];
31         if t1 > left then left := t1;
32       end;
33       inc(ans, i - left);
34     end;
35     writeln(ans);
36   end;
37 end.
View Code


1004.Argestes and Sequence

看我来直播作死:

2014/9/28 22:17  1004在线BIT交到现在都是MLE,于是我把它删了,发誓明天一定要写出离线算法!

2014/9/28 22:51  1004在我无数的WA之后终于A掉了!

 这道题一开始我想到的是线段树,后来发现是求段和于是树状数组(BIT)就可以搞定啦。

但是发现会无限MLE,于是需要一些奇怪的技巧:离线做。

因此我们做10次每次做一位即可。

于是我们现在只考虑某一位上的数如何行统计:

令a[i][j]表示前i个数中j出现的次数。于是操作是单点修改和求前缀和,明显拿BIT维护。

其实还可以分开0到9都做一次,这时候只要700k+(标程)的空间。但是给了3WK的空间就要用满嘛。。。

 1 var
 2   ch : char;
 3   t : longint;
 4   n, m, i, j, di : longint;
 5   bit : array[0..100005, 0..9] of longint;
 6   opt, l, r, d, p, x, a, b, c, ans : array[0..100005] of longint;
 7 
 8 function lowbit(x : longint) : longint;
 9 begin
10   lowbit := x and (-x);
11 end;
12 
13 procedure add(x, y, del : longint);
14 begin
15   while x <= n do begin
16     inc(bit[x, y], del);
17     inc(x, lowbit(x));
18   end;
19 end;
20 
21 function query(x, y : longint) : longint;
22 var
23   res : longint;
24 
25 begin
26   res := 0;
27   if x <> 0 then
28     while x > 0 do begin
29       inc(res, bit[x, y]);
30       dec(x, lowbit(x));
31     end;
32   query := res;
33 end;
34 
35 procedure main;
36 begin
37   readln(n, m);
38   for i := 1 to n do
39     read(a[i]);
40   readln;
41   for i := 1 to m do begin
42     read(ch);
43     if ch = 'Q' then begin
44       opt[i] := 0;
45       readln(l[i], r[i], d[i], p[i]);
46     end else begin
47       opt[i] := 1;
48       readln(x[i], b[i]);
49     end;
50   end;
51 
52   for di := 1 to 10 do begin
53     fillchar(bit, sizeof(bit), 0);
54     c := a;
55     for i := 1 to n do begin
56       add(i, a[i] mod 10, 1);
57       a[i] := a[i] div 10;
58     end;
59     for i := 1 to m do begin
60       if (opt[i] = 1) then begin
61         add(x[i], c[x[i]] mod 10, -1);
62         add(x[i], b[i] mod 10, 1);
63         c[x[i]] := b[i];
64         b[i] := b[i] div 10;
65       end else
66         if d[i] = di then
67           ans[i] := query(r[i], p[i]) - query(l[i] - 1, p[i]);
68     end;
69   end;
70   for i := 1 to m do
71     if opt[i] = 0 then writeln(ans[i]);
72 end;
73 
74 begin
75   readln(t);
76   while t > 0 do begin
77     dec(t);
78     main;
79   end;
80 end.
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/3999051.html