很久没做CF了,记得上一次还是【Codeforces Beta Round #37】……

A. Cableway

题意:是现在有索道上山,索道上的车是每隔1分钟到达一辆,而从山底到山顶要30分钟,这样循环往复。现在索道上的车有R,G,B三种颜色,每辆车可以坐两个人,现在有r,g,b三个人群,每类人群只能坐对应颜色的车上山,0时刻时R车在山底第一个位置,问所有人都是上山,最少需要多少时间。

分析:水题,不解释。

View Code
1 #include <cstdio>
2 #include <cstring>
3
4  #define MAX(a, b) (a > b ? a : b)
5
6  usingnamespace std;
7
8  int main()
9 {
10 int r, g, b;
11
12 scanf("%d %d %d", &r, &g, &b);
13
14 int time_r = ((r +1) /2-1) *3+30;
15 int time_g = ((g +1) /2-1) *3+31;
16 int time_b = ((b +1) /2-1) *3+32;
17
18 printf("%d\n", MAX(time_r, MAX(time_g, time_b)));
19 return0;
20 }

B. African Crossword

题意:给定一个字符矩阵,对于某个字符如果在同行或者同列有相同的字符出现,那么这个字符被标记,最后从上到下、从左到右输出所有未标记字符。

分析:水题,不解释。

View Code
1 #include <cstdio>
2 #include <cstring>
3
4  usingnamespace std;
5
6  constint maxN =128;
7
8  char maze[maxN][maxN];
9  bool dele[maxN][maxN];
10
11  int main()
12 {
13 int nr, nc;
14
15 scanf("%d %d", &nr, &nc);
16 for(int i =0; i < nr; i++)
17 scanf("%s", maze[i]);
18
19 memset(dele, false, sizeof(dele));
20
21 for(int i =0; i < nr; i++)
22 for(int j =0; j < nc; j++)
23 {
24 bool ok =true;
25 for(int k =0; k < nc && ok; k++)
26 if(maze[i][k] == maze[i][j] && k != j) ok =false;
27 for(int k =0; k < nr && ok; k++)
28 if(maze[k][j] == maze[i][j] && k != i) ok =false;
29 if(!ok) dele[i][j] =true;
30 }
31
32 for(int i =0; i < nr; i++)
33 for(int j =0; j < nc; j++)
34 if(!dele[i][j])
35 printf("%c", maze[i][j]);
36 printf("\n");
37
38 return0;
39 }

C. Robbery

题意:现在有N个钻石堆,每个钻石堆都有一些钻石,一些贼想偷取钻石,但是安保机制每隔单位时间会检查相邻两个钻石堆的钻石数量之和,得到N - 1个数,然后与上次检查结果的N - 1个数比较,如果发现不同则报警。现在这些贼在单位时间内能够进行M次操作,他们一共有K个单位时间。能够采取的操作包括:①将某堆钻石中的一颗移动到另一堆;②将某钻石堆中的一颗移动到自己的袋子;③将自己袋子中的一颗移动到某钻石堆;现在求这些贼最多能够偷到多少钻石。

分析:首先,要想保证相邻两堆钻石和不变,那么只能从相邻的两个钻石堆中,从其中一堆移动一颗到另外一堆(假设将 i 堆的一颗钻石移动到 i + 1堆),那么 i 和 i + 1的和保持不变了,但是 i + 1 和 i + 2的和变了,那么我们继续这个过程……这样不难分析出当N为偶数时我们无论如何取不到钻石,只有当N为奇数时才能取得,应为当上述操作执行到最后是,N为奇数,那么最后一堆就多了一颗钻石,我们可以将它移动到自己袋子中即可。

    经过这样分析,我们知道,钻石最多不会超过 i (i 为奇数且 1 <= i <= N)堆中的最小值,还要考虑操作的次数。

View Code
1 #include <cstdio>
2 #include <cstring>
3
4 #define MIN(a, b) (a < b ? a : b)
5
6 usingnamespace std;
7
8 constint maxN =10240;
9
10 int dia[maxN];
11
12 int main()
13 {
14 int n, m, k;
15
16 scanf("%d %d %d", &n, &m, &k);
17 for(int i =0; i < n; i++)
18 scanf("%d", &dia[i]);
19
20 longlong ans;
21 if(n &1)
22 {
23 int need = n /2+1;
24 if(m < need) ans =0;
25 else
26 {
27 ans = dia[0];
28 for(int i =0; i < n; i++)
29 if((i &1) ==0) ans = MIN(ans, dia[i]);
30 longlong all = (longlong)m / need * k;
31 ans = MIN(ans, all);
32 }
33 }
34 else ans =0;
35
36 printf("%I64d\n", ans);
37 return0;
38 }

D. Widget Library

这个题看着比较复杂,所以我直接略过了……

E. Chip Play

题意:给定一个箭头矩阵,每个元素是一个箭头,可以选择任何一个为起点,走过的点即删除并得1分,下一个点为当前点所指示的方向上最近的一个非空元素,若没有则结束。求能够得到的最大分数以及能够得到最大分数的方案数。

分析:简单题,用十字链表加速,直接DFS即可。

View Code
1 #include <cstdio>
2 #include <cstring>
3
4 usingnamespace std;
5
6 constint maxN =5120;
7
8 char maze[maxN][maxN];
9
10 int nr, nc;
11 int L[maxN], R[maxN];
12 int U[maxN], D[maxN];
13
14 void getUDLR()
15 {
16 for(int i =0; i < nr; i++)
17 {
18 int l =-1;
19 for(int j =0; j < nc; j++)
20 if(maze[i][j] !='.')
21 {
22 int idx = i * nc + j;
23 L[idx] = l;
24 if(l !=-1) R[l] = idx;
25 l = idx;
26 }
27 R[l] =-1;
28 }
29
30 for(int i =0; i < nc; i++)
31 {
32 int u =-1;
33 for(int j =0; j < nr; j++)
34 if(maze[j][i] !='.')
35 {
36 int idx = j * nc + i;
37 U[idx] = u;
38 if(u !=-1) D[u] = idx;
39 u = idx;
40 }
41 D[u] =-1;
42 }
43 }
44
45 void del(int i, int j)
46 {
47 int idx = i * nc + j;
48 if(U[idx] !=-1) D[U[idx]] = D[idx];
49 if(D[idx] !=-1) U[D[idx]] = U[idx];
50 if(L[idx] !=-1) R[L[idx]] = R[idx];
51 if(R[idx] !=-1) L[R[idx]] = L[idx];
52 }
53
54 int dfs(int i, int j)
55 {
56 del(i, j);
57
58 int idx = i * nc + j;
59 if(maze[i][j] =='U')
60 {
61 if(U[idx] ==-1) return1;
62 elsereturn1+ dfs(U[idx] / nc, j);
63 }
64 elseif(maze[i][j] =='D')
65 {
66 if(D[idx] ==-1) return1;
67 elsereturn1+ dfs(D[idx] / nc, j);
68 }
69 elseif(maze[i][j] =='L')
70 {
71 if(L[idx] ==-1) return1;
72 elsereturn1+ dfs(i, L[idx] % nc);
73 }
74 elseif(maze[i][j] =='R')
75 {
76 if(R[idx] ==-1) return1;
77 elsereturn1+ dfs(i, R[idx] % nc);
78 }
79
80 //return 0;
81 }
82
83 int main()
84 {
85 scanf("%d %d", &nr, &nc);
86 for(int i =0; i < nr; i++)
87 scanf("%s", maze[i]);
88
89 int num, max =-1;
90 for(int i =0; i < nr; i++)
91 for(int j =0; j < nc; j++)
92 if(maze[i][j] !='.')
93 {
94 getUDLR();
95 int tmp = dfs(i, j);
96 if(tmp > max) max = tmp, num =1;
97 elseif(tmp == max) num++;
98 }
99 printf("%d %d\n", max, num);
100
101 return0;
102 }