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


    比赛链接: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
    ", 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
    ", 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 }
  • 相关阅读:
    iOS 国际化
    iOS iOS7 20px 处理
    iOS 导航栏
    android Tab =viewpager+fragmnet
    Android fragment 想activity 传送数据
    sass sublime text 2 gulp ionic
    HTML5 Notification消息通知
    浅谈设备分辨比
    offsetwidth/clientwidth的区别
    移动端网页布局中需要注意事项以及解决方法总结
  • 原文地址:https://www.cnblogs.com/kirai/p/6189376.html
Copyright © 2020-2023  润新知