码迷,mamicode.com
首页 > 编程语言 > 详细

hihoCoder太阁最新面经算法竞赛18

时间:2016-12-17 14:17:02      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:2.0   interview   ++   1.0   hihocoder   mem   break   下标   位置   

比赛链接:http://hihocoder.com/contest/hihointerview27/problems

A.Big Plus

模拟水

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 505;
 5 int n;
 6 char G[maxn][maxn];
 7 
 8 bool ok(int x, int y) {
 9     return x >= 0 && x < n && y >= 0 && y < n;
10 }
11 int check(int x, int y) {
12     int s = 0;
13     while(ok(x,y-s)&&ok(x,y+s)&&ok(x-s,y)&&ok(x+s,y)&&G[x+s][y]&&G[x-s][y]&&G[x][y+s]&&G[x][y-s]) s++;
14     return s - 1;
15 }
16 
17 int main() {
18     // freopen("in", "r", stdin);
19     memset(G, 0, sizeof(G));
20     while(~scanf("%d", &n)) {
21         for(int i = 0; i < n; i++) {
22             scanf("%s", G[i]);
23         }
24         for(int i = 0; i < n; i++) {
25             for(int j = 0; j < n; j++) {
26                 G[i][j] -= 0;
27             }
28         }
29         int ret = 0;
30         for(int i = 0; i < n; i++) {
31             for(int j = 0; j < n; j++) {
32                 if(G[i][j] == 1) {
33                     ret = max(ret, check(i, j));
34                 }
35             }
36         }
37         printf("%d\n", ret);
38     }
39     return 0;
40 }

 

B.Interval Coverage

初始的目标是[x,y],结束的目标应当是[y,y]: 因为排好序了的,所以先二分,找到一个区间[l,r],使得r尽可能大,并且l不超过x,找到了这么一个l,位置的下标为pos。 那么,现在就需要在排号序后下标为[1,pos]的r中选择最远的,由于用st表预处理了这个东西,所以直接O(1)可以得到最远的r=t(是值)。 其实就不需要关注这个t对应的那条线段是谁了,反正已经符合条件了,那么就更新x=t就行了,目标变成了[t,y]。讨论区的意思是还有O(n)的解法。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     int s, t;
 6 }Node;
 7 const int maxn = 100100;
 8 int n, x, y;
 9 Node p[maxn];
10 
11 int dp[maxn][20];
12 int a[maxn], b[maxn];
13 
14 bool cmp(Node a, Node b) {
15     if(a.s == b.s) return a.t < b.t;
16     return a.s < b.s;
17 }
18 
19 void st() {
20     for(int i = 1; i <= n; i++) dp[i][0] = b[i];
21     int k = int(log(n+1.0)/log(2.0));
22     for(int j = 1; j <= k; j++) {
23         for(int i = 1; i + (1 << j) - 1 <= n; i++) {
24             dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
25         }
26     }
27 }
28 
29 int query(int l, int r) {
30     int k = int(log(r-l+1.0)/log(2.0));
31     return max(dp[l][k], dp[r-(1<<k)+1][k]);
32 }
33 
34 int bs(int lo, int hi, int x) {
35     int pos;
36     while(lo <= hi) {
37         int mid = (lo + hi) >> 1;
38         if(a[mid] <= x) {
39             pos = mid;
40             lo = mid + 1;
41         }
42         else hi = mid - 1;
43     }
44     return pos;
45 }
46 
47 int main() {
48     // freopen("in", "r", stdin);
49     while(~scanf("%d%d%d",&n,&x,&y)) {
50         for(int i = 1; i <= n; i++) {
51             scanf("%d%d",&p[i].s,&p[i].t);
52         }
53         sort(p+1, p+n+1, cmp);
54         for(int i = 1; i <= n; i++) {
55             a[i] = p[i].s;
56             b[i] = p[i].t;
57         }
58         st();
59         int ret = 0;
60         bool flag = 0;
61         while(x < y) {
62             int pos = bs(1, n, x);
63             int t = query(1, pos);
64             if(x == t) {
65                 flag = 1;
66                 break;
67             }
68             x = t;
69             ret++;
70         }
71         if(flag) puts("-1");
72         else printf("%d\n", ret);
73     }
74     return 0;
75 }

 

C.Split Array

题意仅仅是要求分成的小数组里有且仅有k个数字并且连续。那么从头到尾扫一边,每一次都提出一个数字就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 100500;
 5 int n, m, k, a;
 6 int cnt[maxn];
 7 
 8 int main() {
 9     // freopen("in", "r", stdin);
10     int T;
11     scanf("%d", &T);
12     while(T--) {
13         scanf("%d%d",&n,&k);
14         memset(cnt, 0, sizeof(cnt));
15         m = 0;
16         for(int i = 1; i <= n; i++) {
17             scanf("%d", &a);
18             cnt[a]++;
19             m = max(m, a);
20         }
21         bool flag = 0;
22         for(int i = 1; i <= m; i++) {
23             if(flag == 1) break;
24             if(cnt[i] > 0) {
25                 while(cnt[i] > 0) {
26                     for(int j = i; j < i + k; j++) {
27                         if(cnt[j] > 0) cnt[j]--;
28                         else {
29                             flag = 1;
30                             break;
31                         }
32                     }
33                 }
34             }
35         }
36         if(flag) puts("NO");
37         else puts("YES");
38     }
39     return 0;
40 }

 

hihoCoder太阁最新面经算法竞赛18

标签:2.0   interview   ++   1.0   hihocoder   mem   break   下标   位置   

原文地址:http://www.cnblogs.com/kirai/p/6189376.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!