zoukankan      html  css  js  c++  java
  • 2018亚洲区预选赛北京赛站网络赛 D.80 Days 尺取

    题面

    题意:你带着K元要去n个城市,这n个城市是环形的,你可以选择任意一个起点,然后顺时针走,对于每个城市,到达时可以获得a元,但是从这里离开又需要花费b元,问你能否找到一个起点(输出花钱最少的那个),使得你能够走完一圈,不能输出-1

    题解:首先对于环形问题,先把数组复制一次,现在从每个起点开始,满足条件的点就肯定可以进队,其实我们要求的一个i满足,从i到n+i的所有前缀和最小值一定要大于K,因为对于1个i只会进队一次出队一次,所以尺取一下

    (我们一路判断的就是,带着K元能不能加上这段区间>=0,不能的话起点就要顺延,同时终点也顺延,每次只改变头首2个元素)

     1 #include<bits/stdc++.h>
     2 #define N 2000010 
     3 using namespace std;
     4 int T,ans,n,m,cnt,b[N],a[N],c[N];
     5 int main()
     6 {
     7     scanf("%d",&T);
     8     while (T--) 
     9     {
    10         scanf("%d%d",&n,&m);
    11         for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    12         for (int i=1;i<=n;i++) scanf("%d",&b[i]);
    13         for (int i=1;i<=n;i++)
    14         {
    15             c[i]=a[i]-b[i];
    16             c[i+n]=c[i];
    17         }
    18         int l=1,r=1;
    19         long long ans=0;
    20         while (l<=n && r-l+1<=n)
    21         {    
    22             ans+=c[r];
    23             r++;
    24             while (ans+m<0) 
    25             {
    26                 ans-=c[l];
    27                 l++;
    28             }
    29         }
    30         if (l>n) printf("-1
    ");else printf("%d
    ",l);
    31     }
    32     return 0;
    33 }

    比赛时,队友为了实现类似想法,却苦于没听过尺取(我也没听过),和不是很能确定a[i]和b[i]是否能统一的问题,大力码的2种。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mem(a,i) memset(a,i,sizeof(a))
     4 #define rep(i,a,b) for(int i=a;i<=b;++i)
     5 #define per(i,a,b) for(int i=a;i>=b;--i)
     6 #define lowbit(x) (x&-x)
     7 #define pb push_back
     8 #define mp make_pair
     9 #define fi first
    10 #define se second
    11 typedef long long ll;
    12 typedef pair<int,int> pii;
    13 const ll INF=0x3f3f3f3f3f3f3f3f;
    14 const int maxn=1e6+5;
    15 ll a[maxn*2];
    16 ll b[maxn*2];
    17 int n;
    18 ll sum;
    19 int main() {
    20     int caseCnt;
    21     scanf("%d",&caseCnt);
    22     while(caseCnt--) {
    23         scanf("%d%lld",&n,&sum);
    24         rep(i,0,n-1) scanf("%lld",&a[i]);
    25         rep(i,n,2*n-1) a[i]=a[i-n];
    26         rep(i,0,n-1) scanf("%lld",&b[i]);
    27         rep(i,n,2*n-1) b[i]=b[i-n];
    28         int l=0;
    29         while(l<n) {
    30             if(sum+a[l]>=0) {
    31                 break;
    32             }
    33             l++;
    34         }
    35         if(l==n) puts("-1");
    36         else {
    37             int r=l+1;
    38             ll res=sum+a[l];
    39             ll temp=res;
    40             bool ok=false;
    41             while(r<2*n) {
    42                 if(r-l==n) temp=res-b[r-1];
    43                 else temp=min(res-b[r-1],res-b[r-1]+a[r]);
    44                 if(temp<0) break;
    45                 if(r-l==n) {
    46                     ok=true;
    47                     break;
    48                 }
    49                 res=res-b[r-1]+a[r];
    50                 r++;
    51             }
    52             if(ok) {
    53                 printf("%d
    ",l+1);
    54                 continue;
    55             }
    56             int ans;
    57             while(l<n) {
    58                 while(l<r&&temp<0) {
    59                     temp=temp-a[l]+b[l];
    60                     res=res-a[l]+b[l];
    61                     l++;
    62                 }
    63                 res=res-b[r-1]+a[r];
    64                 if(l==r) {
    65                     while(l<n) {
    66                         if(sum+a[l]>=0) {
    67                             break;
    68                         }
    69                         l++;
    70                     }
    71                     if(l==n) break;
    72                     r=l;
    73                     res=sum+a[l];
    74                 }
    75                 r=r+1;
    76                 while(r<2*n) {
    77                     if(r-l==n) temp=res-b[r-1];
    78                     else temp=min(res-b[r-1],res-b[r-1]+a[r]);
    79                     if(temp<0) break;
    80                     if(r-l==n) {
    81                         ans=l+1;
    82                         ok=true;
    83                         break;
    84                     }
    85                     res=res-b[r-1]+a[r];
    86                     r++;
    87                 }
    88                 if(ok) break;
    89             }
    90             if(!ok) puts("-1");
    91             else {
    92                 printf("%d
    ",ans);
    93             }
    94         }
    95     }
    96     return 0;
    97 }
    View Code
      1 #include <cstring>
      2 #include <cstdio>
      3 #include<assert.h>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include<iostream>
      8 #include<queue>
      9 #include<functional>
     10 #include <vector>
     11 #include<set>
     12 #include<string>
     13 #include<map>
     14 #include<unordered_set>
     15 using namespace std;
     16 long long a[2000050], b[2000050];
     17 int main() {
     18     long long i, j, k, n, m, l, r, res, t, c, ans;
     19     scanf("%lld", &t);
     20     while (t--)
     21     {
     22         scanf("%lld%lld", &n, &c);
     23         for (i = 0; i < n; i++) {
     24             scanf("%lld", &a[i]);
     25             a[n + i] = a[i];
     26         }
     27         for (i = 0; i < n; i++) {
     28             scanf("%lld", &b[i]);
     29             b[n + i] = b[i];
     30         }
     31         l = 0;
     32         while (l < n&&c + a[l] < 0)
     33             l++;
     34         if (l == n)
     35         {
     36             printf("-1
    ");
     37             continue;
     38         }
     39         r = l; res = c + a[l];
     40         bool ok = false;
     41         while (l < n)
     42         {
     43             bool flag = false;
     44             long long need = b[r];
     45             if (a[r + 1] < 0 && r + 1 != (n + l)) {
     46                 need -= a[r + 1];
     47                 flag = true;
     48             }
     49             while (r < (n + l) && res >= need)
     50             {
     51                 r++;
     52                 res = res - need;
     53                 if(!flag)
     54                     res = res + a[r];
     55                 flag = false;
     56                 if (r == (n + l - 1)) {
     57                     need = b[r];
     58                     flag = false;
     59                 }
     60                 else {
     61                     need = max(b[r], b[r] - a[r+1]);
     62                     if (a[r+1] < 0)
     63                         flag = true;
     64                 }
     65             }
     66             if (r == (l + n))
     67             {
     68                 ok = true;
     69                 ans = l;
     70                 break;
     71             }
     72             res = res - need;
     73             r++;
     74             while (l < r&&res + b[l] - a[l] < 0) {
     75                 res = res + b[l] - a[l];
     76                 l++;
     77             }
     78             if (!flag)
     79                 res += a[r];
     80             if (l == r)
     81             {
     82                 while (l < n&&c + a[l] < 0)
     83                     l++;
     84                 if (l == n)
     85                 {
     86                     break;
     87                 }
     88                 else
     89                 {
     90                     r = l;
     91                     res = c + a[l];
     92                 }
     93             }
     94             else
     95             {
     96                 res = res + b[l] - a[l];
     97                 l++;
     98             }
     99         }
    100         if (ok)
    101         {
    102             printf("%lld
    ", ans + 1);
    103         }
    104         else
    105             printf("-1
    ");
    106     }
    107 }
    View Code
    Anderyi!
  • 相关阅读:
    Java学习-008-判断文件类型实例
    Java学习-007-Log4J 日志记录配置文件详解及实例源代码
    Java学习-006-三种数据库连接 MySQL、Oracle、sqlserver
    Java学习-005-初学常用的几个经典循环控制源代码
    Selenium2学习-009-WebUI自动化实战实例-007-Selenium 8种元素定位实战实例源代码(百度首页搜索录入框及登录链接)
    TestNG学习-002-annotaton 注解概述及其执行顺序
    C#设计模式之一单例模式(Singleton Pattern)【创建型】
    C#设计模式之二十三解释器模式(Interpreter Pattern)【行为型】
    C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】
    C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】
  • 原文地址:https://www.cnblogs.com/qywhy/p/9692534.html
Copyright © 2011-2022 走看看