zoukankan      html  css  js  c++  java
  • agc034

    A:题意:你有一个1 * n的网格,有些地方是障碍。你有两个人,分别要从a到b和从c到d,一次只能向右跳1步或者两步。求是否可行。

    解:先判断有没有2个连续的障碍,然后判断是否能错车。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 200010;
     4 
     5 char str[N];
     6 
     7 int main() {
     8     int n, a, b, c, d;
     9     scanf("%d%d%d%d%d", &n, &a, &b, &c, &d);
    10     scanf("%s", str + 1);
    11     if(c < d) {
    12         for(int i = a; i < d; i++) {
    13             if(str[i] == '#' && str[i + 1] == '#') {
    14                 printf("No
    ");
    15                 return 0;
    16             }
    17         }
    18         printf("Yes
    ");
    19         return 0;
    20     }
    21     else {
    22         for(int i = a; i < c; i++) {
    23             if(str[i] == '#' && str[i + 1] == '#') {
    24                 printf("No
    ");
    25                 return 0;
    26             }
    27         }
    28         for(int i = b; i <= d; i++) {
    29             if(str[i - 1] == '.' && str[i] == '.' && str[i + 1] == '.') {
    30                 printf("Yes
    ");
    31                 return 0;
    32             }
    33         }
    34         printf("No
    ");
    35         return 0;
    36     }
    37     return 0;
    38 }
    AC代码

    B:题意:你有一个ABC字符串,你能进行的操作就是把某个ABC变成BCA。求最多进行多少次操作。

    解:发现可以把BC看做一个整体。单独的B和C看做障碍物。

    那么对于每一段无障碍物的连续A,BC,求逆序对就好了。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 200010;
     5 
     6 char str[N];
     7 bool vis[N];
     8 
     9 int main() {
    10     
    11     scanf("%s", str + 1);
    12     int n = strlen(str + 1);
    13     for(int i = 1; i <= n; i++) {
    14         if(str[i] == 'C' && str[i - 1] != 'B') {
    15             vis[i] = 1;
    16         }
    17         if(str[i] == 'B' && str[i + 1] != 'C') {
    18             vis[i] = 1;
    19         }
    20     }
    21     LL ans = 0;
    22     for(int l = 1, r; l <= n; l = r + 1) {
    23         while(vis[l]) {
    24             ++l;
    25         }
    26         if(l > n) break;
    27         r = l;
    28         while(!vis[r + 1] && r < n) {
    29             ++r;
    30         }
    31         LL cnt = 0, t = 0;
    32         for(int i = l; i <= r; i++) {
    33             if(str[i] == 'A') {
    34                 ++cnt;
    35             }
    36             else if(str[i] == 'B' && str[i + 1] == 'C') {
    37                 ++i;
    38                 t += cnt;
    39             }
    40         }
    41         ans += t;
    42     }
    43     printf("%lld
    ", ans);
    44     return 0;
    45 }
    AC代码

    C:题意:你有n场考试,满分X分。你的对手每场考试得了bi分。你每学习一个小时就能把某场考试提高1分。你能给每场考试选择一个li~ri之间的加权。求你最少花多少小时才能不比对手考的低。

    解:发现加权要么是li要么是ri。且你比对手高就是ri,否则就是li。

    然后发现如果有两场考试都没有满分,最优策略是把一场考试的分挪到另一场上。

    然后就发现答案一定是若干场满分和一场非满分。这时候就可以排序了,然后二分答案,枚举非满分是哪一场。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 100010;
     5 
     6 struct Node {
     7     LL l, r, b, h;
     8     inline bool operator < (const Node &w) const {
     9         return h > w.h;
    10     }
    11 }node[N];
    12 
    13 LL X, D, sum[N];
    14 int n;
    15 
    16 inline LL cal(LL a, LL i) {
    17     if(a <= node[i].b) {
    18         return a * node[i].l;
    19     }
    20     return node[i].b * node[i].l + (a - node[i].b) * node[i].r;
    21 }
    22 
    23 inline bool check(LL k) {
    24     LL ans = 0, r = k % X, t = k / X;
    25     if(t >= n) {
    26         return sum[n];
    27     }
    28 //    printf("r = %lld t = %lld 
    ", r, t);
    29     for(int i = 1; i <= n; i++) {
    30         if(i <= t) ans = std::max(ans, cal(r, i) + sum[t + 1] - node[i].h);
    31         else {
    32             ans = std::max(ans, cal(r, i) + sum[t]);
    33         }
    34     }
    35     //printf("k = %lld ans = %lld D = %lld 
    ", k, ans, D);
    36     return ans >= D;
    37 }
    38 
    39 int main() {
    40     
    41     scanf("%d%lld", &n, &X);
    42     for(int i = 1; i <= n; i++) {
    43         scanf("%lld%lld%lld", &node[i].b, &node[i].l, &node[i].r);
    44         node[i].h = node[i].b * node[i].l + (X - node[i].b) * node[i].r;
    45         D += node[i].b * node[i].l;
    46     }
    47     std::sort(node + 1, node + n + 1);
    48     for(int i = 1; i <= n; i++) {
    49         sum[i] = sum[i - 1] + node[i].h;
    50     }
    51     LL l = 0, r = 4e18;
    52     while(l < r) {
    53         LL mid = (l + r) >> 1;
    54         if(check(mid)) {
    55             r = mid;
    56         }
    57         else {
    58             l = mid + 1;
    59         }
    60     }
    61     printf("%lld
    ", r);
    62     return 0;
    63 }
    AC代码

    D:题意:给你平面上两组n个点,你要把它们配对,使得曼哈顿距离最大。n <= 1000。

    解:曼哈顿距离有2个绝对值,拆开就是4种情况。直接建4个中转点表示这4种情况,跑最大费用最大流。

      1 #include <bits/stdc++.h>
      2 
      3 #define int LL
      4 
      5 typedef long long LL;
      6 const int N = 2010, INF = 0x3f3f3f3f3f3f3f3fll;
      7 
      8 struct Edge {
      9     int nex, v, c, len;
     10     Edge(){}
     11     Edge(int N, int V, int C, int L) {
     12         nex = N, v = V, c = C, len = L;
     13     }
     14 }edge[2000010]; int tp = 1;
     15 
     16 int e[N], n, tot, d[N], pre[N], flow[N], Time, vis[N];
     17 std::queue<int> Q;
     18 
     19 inline void add(int x, int y, int z, int w) {
     20     edge[++tp] = Edge(e[x], y, z, w);
     21     e[x] = tp;
     22     edge[++tp] = Edge(e[y], x, 0, -w);
     23     e[y] = tp;
     24     return;
     25 }
     26 
     27 inline bool SPFA(int s, int t) {
     28     memset(d, 0x3f, sizeof(d));
     29     Q.push(s);
     30     ++Time;
     31     d[s] = 0;
     32     vis[s] = Time;
     33     flow[s] = INF;
     34     while(Q.size()) {
     35         int x = Q.front();
     36         Q.pop();
     37         vis[x] = 0;
     38         for(int i = e[x]; i; i = edge[i].nex) {
     39             int y = edge[i].v;
     40             if(edge[i].c && d[y] > d[x] + edge[i].len) {
     41                 d[y] = d[x] + edge[i].len;
     42                 pre[y] = i;
     43                 flow[y] = std::min(flow[x], edge[i].c);
     44                 if(vis[y] != Time) {
     45                     vis[y] = Time;
     46                     Q.push(y);
     47                 }
     48             }
     49         }
     50     }
     51     return d[t] < INF;
     52 }
     53 
     54 inline void update(int s, int t) {
     55     int f = flow[t];
     56     while(s != t) {
     57         int i = pre[t];
     58         edge[i].c -= f;
     59         edge[i ^ 1].c += f;
     60         t = edge[i ^ 1].v;
     61     }
     62     return;
     63 }
     64 
     65 inline int solve(int s, int t, int &cost) {
     66     cost = 0;
     67     int ans = 0;
     68     while(SPFA(s, t)) {
     69         //printf("!");
     70         ans += flow[t];
     71         cost += flow[t] * d[t];
     72         update(s, t);
     73     }
     74     return ans;
     75 }
     76 
     77 signed main() {
     78     
     79     scanf("%lld", &n);
     80     int s = 2 * n + 5, t = s + 1, x, y, z;
     81     for(int i = 1; i <= n; i++) {
     82         scanf("%lld%lld%lld", &x, &y, &z);
     83         add(s, i, z, 0);
     84         add(i, 2 * n + 1, z, x + y);
     85         add(i, 2 * n + 2, z, y - x);
     86         add(i, 2 * n + 3, z, x - y);
     87         add(i, 2 * n + 4, z, -x - y);
     88     }
     89     for(int i = 1; i <= n; i++) {
     90         scanf("%lld%lld%lld", &x, &y, &z);
     91         add(n + i, t, z, 0);
     92         add(2 * n + 1, n + i, z, -x - y);
     93         add(2 * n + 2, n + i, z, x - y);
     94         add(2 * n + 3, n + i, z, y - x);
     95         add(2 * n + 4, n + i, z, x + y);
     96     }
     97     //puts("OVER");
     98     int cost = 0;
     99     solve(s, t, cost);
    100     printf("%lld
    ", -cost);
    101     return 0;
    102 }
    AC代码
  • 相关阅读:
    福利贴——爬取美女图片的Java爬虫小程序代码
    select多选 multiple的使用
    Android笔记---点击事件的四种写法
    二叉排序树的插入与删除
    hdu 5269 ZYB loves Xor I &amp;&amp; BestCoder Round #44
    linux 下同步异步,堵塞非堵塞的一些想法
    JavaScript编程随笔
    《从零開始学Swift》学习笔记(Day 51)——扩展构造函数
    What&#39;s Wrong With Hue Oozie Editor?
    2015.7个人反思小结以及兴许规划
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10983191.html
Copyright © 2011-2022 走看看