167 条题解

  • 0
    @ 2016-07-06 20:26:43
          c++
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    long long m,s,t,dp[300001][4],d[300001];
    int main()
    {
        ios::sync_with_stdio(false); 
        cin>>m>>s>>t;
        dp[0][1]=m;
        for(int i=1;i<=t;i++)
        {
            if(dp[i-1][1]>=10)
            {
                dp[i][1]=dp[i-1][1]-10;
                dp[i][0]=dp[i-1][0]+60;
            }
            else
            {
                dp[i][1]=dp[i-1][1]+4;
                dp[i][0]=dp[i-1][0];
            }
            if(d[i-1]+17>dp[i][0])
            {
                d[i]=d[i-1]+17;
            }
            else
            {
                d[i]=dp[i][0];
            }
            if(d[i]>=s)
            {
                cout<<"Yes"<<endl;
                cout<<i<<endl;
                return 0;
            }
        }
        cout<<"No"<<endl;
        cout<<d[t]<<endl;
        return 0;
    } 
    

    ac了

  • 0
    @ 2016-06-20 10:56:21

    枚举时间,贪心选择。
    感谢 冲啊小笼包 的题解。。
    ~~~
    #include <cstdio>
    int m,s,t,x,y,i;
    int main(){
    scanf("%d%d%d",&m,&s,&t);
    for(i = 1;i <= t;i++){
    x += 17;
    if(m >= 10){m -= 10;y += 60;}
    else m += 4;
    if(x < y) x = y;
    if(x >= s){printf("Yes\n%d\n",i);return 0;}
    }
    (x >= s) ? printf("Yes\n%d\n",i) : printf("No\n%d\n",x);
    return 0;
    }
    ~~~

  • 0
    @ 2016-06-15 11:01:40

    记录信息
    评测状态 Accepted
    题目 P1431 守望者的逃离
    递交时间 2016-06-15 10:59:57
    代码语言 C++
    评测机 ShadowShore
    消耗时间 15 ms
    消耗内存 556 KiB
    评测时间 2016-06-15 10:59:58
    评测结果
    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 552 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 552 KiB, score = 10
    测试数据 #7: Accepted, time = 15 ms, mem = 552 KiB, score = 10
    测试数据 #8: Accepted, time = 0 ms, mem = 552 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    Accepted, time = 15 ms, mem = 556 KiB, score = 100
    代码
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<string>
    using std::swap;
    using std::sort;
    int f[15],n,d,m,t,k,dist,time;
    inline int read()
    {
    int c=getchar(),temp=0;
    for(;c<48||57<c;c=getchar());
    do
    {
    temp=(temp<<3)+(temp<<1)+c-48;
    c=getchar();
    }while(48<=c&&c<=57);
    return temp;
    }
    inline int max(int x,int y)
    {
    x-=y;return y+(x&(~(x>>31)));
    }
    int main()
    {
    n=read();m=read();t=read();
    k=n/10;n%=10;
    if(k*60>=m)
    {
    printf("Yes\n%d",(m+59)/60);
    return 0;
    }
    if(k>=t)
    {
    printf("No\n%d",t*60);
    return 0;
    }
    m-=k*60;dist+=k*60;
    t-=k;time+=k;
    k=std::min(m/120,t/7)-1;
    k&=~(k>>31);
    m-=k*120;dist+=k*120;
    t-=k*7;time+=k*7;
    for(int i=1;i<=t;++i)
    {
    if(n>=10) n-=10,d+=60;
    else n+=4;
    f[i]=max(f[i-1]+17,d);
    if(f[i]>=m)
    {
    printf("Yes\n%d",time+i);
    return 0;
    }
    }
    printf("No\n%d",dist+f[t]);
    return 0;
    }

  • 0
    @ 2015-12-16 19:24:30

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    using namespace std;
    const int N = 300000;
    bool flag = false;
    int m,s,t,f[N];
    int main(){
    scanf("%d%d%d",&m,&s,&t);
    for(int i = 1;i <= t;i ++){
    if(m >= 10){
    f[i] = f[i - 1] + 60;
    m -= 10;
    }
    else {
    f[i] = f[i - 1];
    m += 4;
    }
    }
    for(int i = 1;i <= t;i ++){
    if(f[i] < f[i - 1] + 17)f[i] = f[i - 1] + 17;
    if(f[i] >= s){ printf("Yes\n%d",i);break; }
    else if(i == t)printf("No\n%d",f[i]);
    }
    return 0;
    }

  • 0
    @ 2015-10-23 14:22:27

    超简单 清晰的做法!
    http://www.ofsxb.com/archives/486

    • @ 2017-08-23 21:50:43

      兄弟你网站挂了

  • 0
    @ 2015-08-10 11:16:12

    蒟蒻求本题的DP背包做法。。。

  • 0
    @ 2015-08-08 11:46:20

    记录信息
    评测状态 Accepted
    题目 P1431 守望者的逃离
    递交时间 2015-08-07 21:51:01
    代码语言 C++
    评测机 VijosEx
    消耗时间 90 ms
    消耗内存 520 KiB
    评测时间 2015-08-07 21:51:02
    评测结果
    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 520 KiB, score = 10
    测试数据 #1: Accepted, time = 1 ms, mem = 520 KiB, score = 10
    测试数据 #2: Accepted, time = 2 ms, mem = 520 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 520 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 520 KiB, score = 10
    测试数据 #5: Accepted, time = 36 ms, mem = 520 KiB, score = 10
    测试数据 #6: Accepted, time = 15 ms, mem = 520 KiB, score = 10
    测试数据 #7: Accepted, time = 0 ms, mem = 520 KiB, score = 10
    测试数据 #8: Accepted, time = 31 ms, mem = 520 KiB, score = 10
    测试数据 #9: Accepted, time = 5 ms, mem = 520 KiB, score = 10
    Accepted, time = 90 ms, mem = 520 KiB, score = 100
    代码
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    int run[35];
    int prerun[35];
    int main()
    {
    int m,s,t;
    scanf("%d%d%d",&m,&s,&t);
    if((s+59)/60<=(m/10))
    {
    printf("Yes\n");
    printf("%d",(s+59)/60);
    return 0;
    }
    int now=m%10;
    m/=10;

    if(t<m)
    {
    printf("No\n");
    printf("%d",t*60);
    return 0;
    }
    t-=m;
    for(int i=0;i<=32;i++)
    {
    prerun[i]=-100000000;
    run[i]=-100000000;
    }
    prerun[now]=m*60;
    for(int i=1;i<=t;i++)
    {
    for(int j=0;j<=20;j+=1)
    {
    run[j]=prerun[j]+17;
    if(j<=18)
    run[j]=max(run[j],prerun[j+10]+60);
    if(j>=4)
    run[j]=max(run[j],prerun[j-4]);
    if(run[j]>=s)
    {
    printf("Yes\n");
    printf("%d",i+m);
    return 0;
    }
    }
    memcpy(prerun,run,sizeof(run));
    }
    int maxans=run[0];
    for(int i=1;i<=20;i++)
    maxans=max(maxans,run[i]);
    printf("No\n%d",maxans);
    }

    • @ 2015-09-23 19:18:21

      16 2532 1 你输出了负无穷

  • 0
    @ 2015-07-28 16:34:04

    …………………………是Yes不是YES。。。是No不是NO。。。!!!!!我也是跪下了……

  • 0
    @ 2015-07-15 14:40:22

    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;

    int a[1000000];

    int main()
    {
    int m,s,t;
    cin>>m>>s>>t;
    int bri=0;
    int i;
    for(i=0; i<=t; ){
    while(m<10){
    m+=4;
    i++;
    a[i] = a[i-1];
    }
    i++;
    bri+=60;
    a[i] = bri;
    m-=10;
    }
    for(i=1; i<=t; i++)
    a[i] = max(a[i],a[i-1]+17);
    int flg=0;
    for(i=1; i<=t; i++)
    if(a[i] > s){
    flg=1;
    break;
    }
    if(flg == 1)
    cout<<"Yes"<<endl<<i;
    else
    cout<<"No"<<endl<<a[t];
    system("pause");
    return 0;
    }

  • 0
    @ 2015-07-01 10:45:42

    var
    a,b,c,d,e,f:longint;
    begin
    read(a,b,c);
    e:=0;
    f:=0;
    for d := 1 to c do
    begin
    e:=e+17;
    if a>=10 then
    begin
    a:=a-10;
    f:=f+60;
    end
    else a:=a+4;
    if f>e then e:=f;
    if e>=b then
    begin
    writeln('Yes');
    write(d);
    halt;
    end;
    end;
    if e>=b then
    begin
    writeln('Yes');
    write(d);
    halt;
    end;
    writeln('No');
    write(e);
    end.

  • 0
    @ 2015-05-28 17:19:55

    这个方法应该不算贪心:计算出只用闪烁法术(法力不够就停着不走)时每秒位置

    然后再循环,每秒都用走的,若用走的不用如闪烁法术的,就取用闪烁法术的位置

    否则取用走的位置

    这种方法避免了我的思维障碍(不再需要使用贪心时还考虑休息问题)

    #include<stdio.h>
    int main( )
    {
    int g[300001]={0},m,s,t,i,ans,x=0,flag=0;
    scanf("%d %d %d",&m,&s,&t);

    for(i=1;i<=t;i++)
    {
    if(m>=10) {m=m-10;g[i]=g[i-1]+60;}
    else {m=m+4;g[i]=g[i-1];}

    }

    for(i=1;i<=t;i++)
    {
    ans=ans+17;

    if(ans<=g[i]) ans=g[i];

    if(ans>=s) {printf("Yes\n%d",i);flag=1;break;}
    }

    if(flag==0) {printf("No\n");printf("%d",ans);}

    return 0;
    }

  • 0
    @ 2015-04-17 21:02:45

    贪心1:很显然\({m}\geq{10}\)时一定用闪烁。
    贪心2:注意到对于每一个7s,闪烁+休息的距离至少为\(120\),而走路的距离总是\(119\),而一定存在一个\(0\leq a \leq 6\)满足\({a}\equiv {t}\pmod{7}\),所以在t>6 and s>=119时用闪烁+休息。
    剩下的部分搜索一下就行了。

    Pascal Code

    var
        m,s,t,t1,s1:longint;  
    //s表示剩下的路程,t表示剩下的时间,s1、t1表示剩下的路程和时间
        bestt,bests:longint;
    //bestt表示能逃离时最多剩下的时间,bests表示不能逃离时最少剩下的路程
    procedure qmove;
    begin
        while m<10 do begin m:=m+4;dec(t);end;
        m:=m-10;
        s:=s-60;
        dec(t);
    end;
    procedure dfs(m,s,t:longint);  //搜索
    begin
      if s<=0 then begin if t>bestt then bestt:=t;exit;end;
      if t=0 then begin if s<bests then bests:=s;exit;end;
      if m>=10 then begin dfs(m-10,s-60,t-1);exit;end;  //贪心1
      dfs(m+4,s,t-1);  //休息
      dfs(m,s-17,t-1);  //走路
    end;
    begin
      readln(m,s,t);
      t1:=t;
      s1:=s;
      m:=m div 2 *2;
      while (m>=10) and (s>0) and (t>0) do
        qmove;                //贪心1
      if s<=0 then begin writeln('Yes');writeln(t1-t);halt;end;  //能逃离
      if t<=0 then begin writeln('No');writeln(s1-s);halt;end;  //不能逃离
      while (t>6) and (s>=119) do
        qmove;              //贪心2
      bestt:=-maxlongint;
      bests:=maxlongint;
      dfs(m,s,t);
      if bestt>-maxlongint then begin writeln('Yes');writeln(t1-bestt);halt;end;  //能逃离
      if bests<maxlongint then begin writeln('No');writeln(s1-bests);halt;end;  //不能逃离
    end.
    
  • 0
    @ 2015-02-09 17:47:08

    考虑各种情况模拟即可,时空复杂度都是O(1)

  • 0
    @ 2015-01-24 19:07:24

      贪心,用闪烁的平均速度(跑完后恢复为原来的魔力值)为17.14+,比正常跑地快一点,因此能用闪烁就尽量用,用不了就恢复魔法(岛要没嘞,还不快跑!)。
    #include <cmath>
    #include <iostream>
    using namespace std;

    int t, s, m, mt = 1e6, md;

    inline int run(int rest) {
    if(rest <= 0)
    return 0;
    return rest / 17 + (rest % 17 ? 1 : 0);
    }

    int main() {
    cin >> m >> s >> t;
    for(int i = 0, mp = m, d = 0; i <= t; ++i) {
    mt = min(mt, i + run(s - d));
    md = max(md, d + 17 * (t - i));
    if(mp >= 10)
    mp -= 10, d += 60;
    else
    mp = min(mp + 4, m);
    }
    if(mt <= t)
    cout << "Yes" << endl << mt << endl;
    else
    cout << "No" << endl << md << endl;
    return 0;
    }

  • 0
    @ 2014-09-30 08:41:06

    感谢楼下大神的算法 一开始我想的是模拟 就是各种if各种特判 结果发现特判非常多根本停不下来- -

  • 0
    @ 2014-08-21 16:14:14

    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 560 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #2: Accepted, time = 15 ms, mem = 560 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 564 KiB, score = 10
    测试数据 #4: Accepted, time = 15 ms, mem = 556 KiB, score = 10
    测试数据 #5: Accepted, time = 15 ms, mem = 556 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 556 KiB, score = 10
    测试数据 #7: Accepted, time = 15 ms, mem = 556 KiB, score = 10
    测试数据 #8: Accepted, time = 15 ms, mem = 560 KiB, score = 10
    测试数据 #9: Accepted, time = 15 ms, mem = 556 KiB, score = 10
    Accepted, time = 90 ms, mem = 564 KiB, score = 100

    #include<iostream>
    using namespace std;
    int main()
    {
    long m, s, t, i, a = 0, b = 0;
    cin >> m >> s >> t;
    for(i = 1; i <= t; i++)
    {
    a += 17;

    if(m >= 10)
    {
    m -= 10;
    b += 60;
    }
    else m += 4;

    if(b > a) a = b;

    if(a >= s)
    {
    cout << "Yes" << endl << i;
    return 0;
    }
    }

    if(a >= s)
    {
    cout << "Yes" << endl << i - 1;
    return 0;
    }

    cout << "No" << endl << a;
    return 0;
    }

    • @ 2015-07-30 22:10:27

      我去,机智啊,之前想了半小时动归还没出来,看见这代码豁然开朗!

  • 0
    @ 2014-08-07 10:16:06

    #include<iostream>
    using namespace std;
    main()
    {
    long m,s,t,i,a=0,b=0;
    cin>>m>>s>>t;
    for(i=1;i<=t;i++)
    {
    a+=17;
    if(m>=10)
    {
    m-=10;
    b+=60;
    }
    else
    m+=4;
    if(b>a)
    a=b;
    if(a>=s)
    {
    cout<<"Yes"<<endl<<i;
    return 0;
    }
    }
    if(a>=s)
    {
    cout<<"Yes"<<endl<<i-1;
    return 0;
    }
    cout<<"No"<<endl<<a;
    }

  • 0
    @ 2014-05-14 17:57:38

    var
    a,b,c,d,e,f:longint;
    begin
    read(a,b,c);
    e:=0;
    f:=0;
    for d := 1 to c do
    begin
    e:=e+17;
    if a>=10 then
    begin
    a:=a-10;
    f:=f+60;
    end
    else a:=a+4;
    if f>e then e:=f;
    if e>=b then
    begin
    writeln('Yes');
    write(d);
    halt;
    end;
    end;
    if e>=b then
    begin
    writeln('Yes');
    write(d);
    halt;
    end;
    writeln('No');
    write(e);
    end.

  • 0
    @ 2013-11-05 22:12:09

    评测结果

    编译成功

    foo.cpp: In function 'int main()':
    foo.cpp:69:14: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]

    测试数据 #0: Accepted, time = 0 ms, mem = 564 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 556 KiB, score = 10

    测试数据 #2: Accepted, time = 0 ms, mem = 560 KiB, score = 10

    测试数据 #3: Accepted, time = 0 ms, mem = 560 KiB, score = 10

    测试数据 #4: Accepted, time = 0 ms, mem = 564 KiB, score = 10

    测试数据 #5: Accepted, time = 0 ms, mem = 564 KiB, score = 10

    测试数据 #6: Accepted, time = 15 ms, mem = 568 KiB, score = 10

    测试数据 #7: Accepted, time = 0 ms, mem = 568 KiB, score = 10

    测试数据 #8: Accepted, time = 0 ms, mem = 560 KiB, score = 10

    测试数据 #9: Accepted, time = 0 ms, mem = 560 KiB, score = 10

    Accepted, time = 15 ms, mem = 568 KiB, score = 100
    代码

    #include <iostream>
    #include <stdio.h>
    #include <math.h>

    using namespace std;

    int M , S , T;
    int t;
    int s1 , s2;
    int flag;

    int main()
    {
    while( scanf( "%d %d %d" , &M , &S , &T ) != EOF )
    {
    s1 = s2 = t = 0;
    flag = 0;
    while( M >= 10 && t < T )
    {
    M -= 10;
    s1 += 60;
    s2 += 60;
    t++;
    if( s1 >= S )
    {
    flag = 1;
    cout << "Yes\n" << t << endl;
    break;
    }
    }
    while( t < T && flag != 1 )
    {
    if( M >= 10 )
    {
    M -= 10;
    s1 += 60;
    s2 += 17;
    t++;
    continue;
    }
    if( T - t == 2 && M <= 5 )
    s1 += 17;
    else if( T - t == 1 && M <= 9 )
    s1 += 17;
    else if( S - s1 <= 34 )
    s1 += 17;
    else if( M <= 5 && S - s1 <= 51 )
    s1 += 17;
    else if( M <= 1 && S - s1 <= 68 )
    s1 += 17;
    else
    M += 4;
    s2 += 17;
    t++;
    if( s1 >= S )
    {
    cout << "Yes\n" << t << endl;
    flag = 1;
    break;
    }
    else if( s2 >= S )
    {
    cout << "Yes\n" << t << endl;
    flag = 1;
    break;
    }
    //cout << s1 << " " << s2 << " " << t << endl;
    }
    if( !flag )
    if( s1 >= s2 )
    cout << "No\n" << s1 << endl;
    else
    cout << "No\n" << s2 << endl;
    }
    return 0;
    }

  • 0
    @ 2013-08-23 16:16:39

    测试数据 #0: Accepted, time = 0 ms, mem = 812 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 812 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 812 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #7: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #8: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 816 KiB, score = 10
    Accepted, time = 0 ms, mem = 816 KiB, score = 100

    水炸天~~~貌似普通贪心就秒杀了。CODE:

    var m,s,t,i,s1,s2:longint;
    begin
    read(m,s,t);s1:=0;s2:=0;
    for i:=1 to t do begin
    s1:=s1+17;
    if m>=10 then begin m:=m-10;s2:=s2+60;end else m:=m+4;
    if s2>s1 then s1:=s2;
    if s1>=s then begin writeln('Yes');writeln(i);halt;end;
    end;
    if s1>=s then begin writeln('Yes');writeln(i);halt;end;
    writeln('No');writeln(s1);
    end.

    • @ 2013-10-30 08:42:53

      这样的贪心肯定是错的好吗

    • @ 2013-10-30 09:08:32

      抱歉,看错了。。= =

信息

ID
1431
难度
5
分类
动态规划 | 背包 点击显示
标签
递交数
6158
已通过
1917
通过率
31%
被复制
22
上传者