zoukankan      html  css  js  c++  java
  • 2050 Programming Competition (CCPC)

    Pro&Sol

    链接: https://pan.baidu.com/s/17Tt3EPKEQivP2-3OHkYD2A 提取码: wbnu 复制这段内容后打开百度网盘手机App,操作更方便哦

    6491 时间间隔

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e5+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 char s[maxn],str[5]="2050";
    20 
    21 int main()
    22 {
    23     int t,len,i;
    24     scanf("%d",&t);
    25     while (t--)
    26     {
    27         scanf("%s",s);
    28         len=strlen(s);
    29         for (i=0;i<len;i++)
    30             if (s[i]!=str[i%4])
    31                 break;
    32         if (i==len && len%4==0)
    33             printf("Yes
    ");
    34         else
    35             printf("No
    ");
    36     }
    37     return 0;
    38 }
    39 /*
    40 
    41 */

    6491 时间间隔

    S距离2050年1月1日0点0时0分多少秒

    2050_value-this_value 而不是差值绝对值模100 (不过感觉有点牵强)

    负数的结果进行相应处理

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e4+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 
    20 
    21 int main()
    22 {
    23     int t,a,b,c,d,e,f;
    24     scanf("%d",&t);
    25     while (t--)
    26     {
    27         scanf("%d-%d-%d %d:%d:%d",&a,&b,&c,&d,&e,&f);
    28         printf("%d
    ",((-e*60-f)%100+100)%100);
    29     }
    30     return 0;
    31 }
    32 /*
    33 7
    34 2023-12-01 03:12:12
    35 68
    36 2024-05-01 03:12:12
    37 68
    38 3000-03-01 23:00:59
    39 41
    40 6000-03-01 00:00:00
    41 0
    42 6661-01-12 13:34:45
    43 15
    44 6661-01-12 13:34:46
    45 14
    46 2049-12-31 23:59:59
    47 1
    48 */
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e4+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    20 
    21 ll cal(int a,int b,int c,int d,int e,int f)
    22 {
    23     ll sum=0;
    24     int i;
    25     for (i=1;i<a;i++)
    26         if (i%4==0 && (i%400==0 || i%100!=0))
    27             sum+=1ll*366*24*60*60;
    28         else
    29             sum+=1ll*365*24*60*60;
    30     if (i%4==0 && (i%400==0 || i%100!=0))
    31         mon[2]=29;
    32     for (i=1;i<b;i++)
    33         sum+=1ll*24*60*60*mon[i];
    34     sum+=1ll*24*60*60*(c-1)+d*60*60+e*60+f;
    35     return sum;
    36 }
    37 
    38 int main()
    39 {
    40     int t,a,b,c,d,e,f;
    41     ll tot=0;
    42     tot=cal(2050,1,1,0,0,0);
    43     scanf("%d",&t);
    44     while (t--)
    45     {
    46         scanf("%d-%d-%d %d:%d:%d",&a,&b,&c,&d,&e,&f);
    47         printf("%lld
    ",(tot-cal(a,b,c,d,e,f)%100+100)%100);
    48     }
    49     return 0;
    50 }
    51 /*
    52 
    53 */
     1 import java.text.SimpleDateFormat;
     2 import java.util.*;
     3 
     4 public class Main {
     5     public static void main(String[] args) throws Exception {
     6         //upper lower
     7         SimpleDateFormat tf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     8         Date t1=tf.parse("2050-01-01 00:00:00");
     9         Scanner in=new Scanner(System.in);
    10         String s;
    11         int t;
    12         t=in.nextInt();
    13         s=in.nextLine();
    14         while (t-->0) {
    15             s=in.nextLine();
    16             Date t2=tf.parse(s);
    17             //System.out.println(t2);    //test
    18             //System.out.println(t2.getTime()/1000);
    19             //ms
    20             System.out.println(( Math.abs(t1.getTime()-t2.getTime()) )/1000%100);
    21 //            System.out.println(dif);
    22         }
    23         in.close();
    24     }
    25 }
    26 /*
    27 7
    28 2023-12-01 03:12:12
    29 2024-05-01 03:12:12
    30 2000-03-01 23:00:59
    31 2049-03-01 00:00:00
    32 2048-01-12 13:34:45
    33 2023-01-12 13:34:46
    34 2036-12-31 23:59:59
    35 
    36 68
    37 68
    38 41
    39 0
    40 15
    41 14
    42 1
    43 */

    6492 分宿舍

    贪心,参见下方注释

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e5+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 ll n,m,k,a,b,c;
    20 
    21 ll cal(ll g)
    22 {
    23     /*
    24     替代 2*3=3*2
    25     两人间 <=2
    26     三人间 <=1
    27     */
    28     ll tot=1e18;
    29     int i;
    30     for (i=0;i<=2;i++)
    31         tot=min(tot,i*a+(g-i*2+2)/3*b);
    32     for (i=0;i<=1;i++)
    33         tot=min(tot,(g-i*3+1)/2*a+i*b);
    34     return tot;
    35 }
    36 
    37 int main()
    38 {
    39     ll tot;
    40     int t,i;
    41     scanf("%d",&t);
    42     while (t--)
    43     {
    44         scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b,&c);
    45         tot=1e18;
    46         for (i=k;i>=0;i--)
    47             tot=min(tot,c*i+cal(n+k-i)+cal(m+k-i));
    48 
    49         printf("%lld
    ",tot);
    50     }
    51     return 0;
    52 }
    53 /*
    54 1
    55 1000 1000 1000 1000000000 1000000000 1000000000
    56 
    57 1
    58 1 1 0 3 2 1
    59 */

    预处理f[x],x个人,需要花费的最小代码。对于每个k对应的n+k和m+k,O(1)得到答案。

    ( f[i]=min(f[i-2]+a,f[i-3]+b) \ f[j]=0 j<=0 )

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=2e3+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 ll n,m,k,a,b,c,f[maxn];
    20 
    21 int main()
    22 {
    23     ll tot;
    24     int t,i,lim;
    25     scanf("%d",&t);
    26     while (t--)
    27     {
    28         scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b,&c);
    29         memset(f,sizeof(0x3f),sizeof(f));
    30         lim=max(n+k,m+k);
    31         f[0]=0;
    32         for (i=0;i<=lim;i++)
    33             if (i<2)
    34                 f[i]=min(f[i],a);
    35             else
    36                 f[i]=min(f[i],f[i-2]+a);
    37         for (i=0;i<=lim;i++)
    38             if (i<3)
    39                 f[i]=min(f[i],b);
    40             else
    41                 f[i]=min(f[i],f[i-3]+b);
    42 
    43         tot=1e18;
    44         for (i=k;i>=0;i--)
    45             tot=min(tot,c*i+f[n+k-i]+f[m+k-i]);
    46         printf("%lld
    ",tot);
    47     }
    48     return 0;
    49 }
    50 /*
    51 1
    52 1000 1000 1000 1000000000 1000000000 1000000000
    53 
    54 1
    55 1 1 0 3 2 1
    56 */

    暴力,不会超时

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <iostream>
    using namespace std;
    
    #define ll long long
    
    const int maxn=1e5+10;
    const int inf=1e9;
    const double eps=1e-8;
    
    int main()
    {
        int t;
        ll n,m,k,a,b,c,i,j,tot,sum,x,y;
        scanf("%d",&t);
        while (t--)
        {
            scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b,&c);
            tot=1e18;
            for (i=k;i>=0;i--)
            {
                sum=c*i;
    
                x=n+k-i;
                y=1e18;
                for (j=0;j<=(x+1)/2;j++)
                    y=min(y,j*a+(x-j*2+2)/3*b);
                sum+=y;
    
                x=m+k-i;
                y=1e18;
                for (j=0;j<=(x+1)/2;j++)
                    y=min(y,j*a+(x-j*2+2)/3*b);
                sum+=y;
    
                tot=min(tot,sum);
            }
    
            printf("%lld
    ",tot);
        }
        return 0;
    }
    /*
    1
    1000 1000 1000 1000000000 1000000000 1000000000
    
    1
    1 1 0 3 2 1
    */

    以下方法是错误的

    6493 PASS

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e4+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 int g[maxn],a[maxn];
    20 
    21 int main()
    22 {
    23     int t,n,m,k,i,tot;
    24     scanf("%d",&t);
    25     while (t--)
    26     {
    27         scanf("%d%d%d",&n,&m,&k);
    28         memset(g,0,sizeof(g));
    29         for (i=1;i<=n;i++)
    30         {
    31             scanf("%d",&a[i]);
    32             g[a[i]]++;
    33         }
    34         for (i=1;i<=m;i++)
    35             g[i]/=k;
    36         tot=0;
    37         for (i=1;i<=n/2;i++)
    38         {
    39             g[a[i]]--;
    40             if (g[a[i]]>=0)
    41                 tot++;
    42         }
    43         printf("%d
    ",tot);
    44     }
    45     return 0;
    46 }
    47 /*
    48 
    49 */

    1005球赛

    一开始猜测贪心有可能是错的,所以选择使用dp

    ( egin{equation*}egin{split}&condition quad (a,b) quad -> quad condition (x,y) quad + quad c(+1/+0)\&(10,k)/(k,10) quad -> quad (0,0) quad [(11,k)/(k,11)] quad + quad 1 quad k<=9\&(10,11)/(11,10) quad -> quad (0,0) quad [(10,12)/(12,10)] quad +1\&(10,11)/(11,10) quad -> quad (10,10) quad [(11,11)]\&f[x][y]=max(f[a][b]+c)end{split}end{equation*} )

     

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <iostream>
    using namespace std;
    
    #define ll long long
    
    const int maxn=1e4+10;
    const int inf=1e9;
    const double eps=1e-8;
    
    char str[maxn];
    int f[maxn][12][12];
    
    int main()
    {
        int T,g,len,i,j,k,s,t;
        scanf("%d",&T);
        while (T--)
        {
    
            scanf("%s",str+1);
            len=strlen(str+1);
            for (i=0;i<=len;i++)
                for (j=0;j<12;j++)
                    for (k=0;k<12;k++)
                        f[i][j][k]=-1;
            f[0][0][0]=0;
            for (i=1;i<=len;i++)
            {
                for (j=0;j<12;j++)
                    for (k=0;k<12;k++)
                        if (f[i-1][j][k]!=-1)
                        {
                            if (str[i]=='A' || str[i]=='?')
                            {
                                s=j+1;
                                t=k;
                                if (s==11 && t==11)
                                    s=10,t=10;
                                if ((s>=11 && s-t>=2) || (t>=11 && t-s>=2))
                                    f[i][0][0]=max(f[i][0][0],f[i-1][j][k]+1);
                                else
                                    f[i][s][t]=max(f[i][s][t],f[i-1][j][k]);
                            }
                            if (str[i]=='B' || str[i]=='?')
                            {
                                s=j;
                                t=k+1;
                                if (s==11 && t==11)
                                    s=10,t=10;
                                if ((s>=11 && s-t>=2) || (t>=11 && t-s>=2))
                                    f[i][0][0]=max(f[i][0][0],f[i-1][j][k]+1);
                                else
                                    f[i][s][t]=max(f[i][s][t],f[i-1][j][k]);
                            }
                        }
    
            }
            g=0;
            for (i=0;i<12;i++)
                for (j=0;j<12;j++)
                    g=max(g,f[len][i][j]);
            printf("%d
    ",g);
        }
        return 0;
    }
    /*
    1
    AAAAAAAAAAA
    ??????????????????????
    ?????
    */

    6495 冰水挑战

    无贪心方法等。应该往dp想。c不应该作为一维。应该很自然就能想到。。。

    ( 前i个挑战中,选择j个挑战,剩余的最大体力\ egin{equation*}egin{split}&f[i][j]=f[i-1][j]+c_{i}\&f[i][j]=max(f[i][j],min(f[i-1][j-1],b_{i})-a_{i}+c_{i})) quad if \, min(f[i-1][j-1],b_{i})-a_{i}>0 \, , \, i>0 \end{split}end{equation*} )

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e3+10;
    16 const ll inf=1e18;
    17 const double eps=1e-8;
    18 
    19 ll f[maxn][maxn];
    20 
    21 int main()
    22 {
    23     int t,n,i,j;
    24     ll m,a,b,c;
    25     scanf("%d",&t);
    26     while (t--)
    27     {
    28         scanf("%d%lld",&n,&m);
    29         for (i=0;i<=n;i++)
    30             for (j=1;j<=n;j++)
    31                 f[i][j]=-inf;
    32         f[0][0]=m;
    33         for (i=1;i<=n;i++)
    34         {
    35             scanf("%lld%lld%lld",&a,&b,&c);
    36             f[i][0]=f[i-1][0]+c;
    37             for (j=1;j<=n;j++)
    38             {
    39                 f[i][j]=f[i-1][j]+c;
    40                 if (min(f[i-1][j-1],b)-a>0)
    41                     f[i][j]=max(f[i][j],min(f[i-1][j-1],b)-a+c);
    42             }
    43         }
    44         for (j=n;j>=1;j--)
    45             if (f[n][j]>0)
    46                 break;
    47         printf("%d
    ",j);
    48     }
    49     return 0;
    50 }
    51 /*
    52 
    53 */

    6496 大厦

    1.新方法

    用下面的方法求矩形

    对于每个横坐标小块i,求纵坐标上下限[ d[i] , u[i] ]。

    若对于某个纵坐标,横坐标小块为[x1,x2],则往上,[x3,x4],有x1<=x3 , x4<=x2。往下,同理。(里大,外小)

    对于横坐标小块[x1,x2],求[x1,x2]的纵坐标上下限([ max(d[x1],d[x1+1],...,d[x2]) , min(u[x1],u[x1+1],...,u[x2])  ])

    st/线段树处理。

    O(T*(n*m+n*n/2))

    横坐标小块12;13;14;..;23;24;...;n-1 n

    1*n 个数n+(n-1)+(n-2)+...+1 = n*(n+1)/2

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e3+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 const ll mod=1e9+7;
    19 
    20 int c1[maxn],c2[maxn],d[maxn],u[maxn];
    21 
    22 int main()
    23 {
    24     ll sum;
    25     int t,w,h,n,m,i,j,down,up;
    26     scanf("%d",&t);
    27     while (t--)
    28     {
    29         scanf("%d%d%d%d",&w,&h,&n,&m);
    30         for (i=1;i<=n;i++)
    31             scanf("%d",&c1[i]);
    32         for (i=1;i<=m;i++)
    33             scanf("%d",&c2[i]);
    34         memset(d,0x3f,sizeof(d));
    35         memset(u,0,sizeof(u));
    36 
    37         sort(c1+1,c1+n+1);
    38         sort(c2+1,c2+m+1);
    39         for (i=1;i<=n;i++)
    40             ///其实用二分更快
    41             for (j=1;j<=m;j++)
    42                 if (0<=c1[i]+c2[j] && c1[i]+c2[j]<=w*2
    43                     && 0<=c1[i]-c2[j] && c1[i]-c2[j]<=h*2)  ///w*2 h*2 int range
    44                         d[i]=min(d[i],j),u[i]=max(u[i],j);
    45 
    46         sum=0;
    47         for (i=1;i<n;i++)
    48         {
    49             down=d[i],up=u[i];
    50             for (j=i+1;j<=n;j++)
    51             {
    52                 down=max(down,d[j]),up=min(up,u[j]);
    53                 if (up>=down)
    54                     sum=(sum+1ll*(up-down)*(up-down+1)/2)%mod;
    55             }
    56         }
    57         printf("%lld
    ",sum); ///ll
    58     }
    59     return 0;
    60 }
    61 /*
    62 
    63 */

    2.bitset(题解)

    time(/32)

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 #include <bitset>
    12 using namespace std;
    13 
    14 #define ll long long
    15 
    16 const int maxn=1e3+10;
    17 const int maxm=1e3+10;
    18 const int inf=1e9;
    19 const double eps=1e-8;
    20 const ll mod=1e9+7;
    21 
    22 int c1[maxn],c2[maxn];
    23 bitset<maxm> f[maxn];
    24 
    25 int main()
    26 {
    27     ll sum;
    28     int t,w,h,n,m,i,j,g;
    29     scanf("%d",&t);
    30     while (t--)
    31     {
    32         scanf("%d%d%d%d",&w,&h,&n,&m);
    33         for (i=1;i<=n;i++)
    34             scanf("%d",&c1[i]);
    35         for (i=1;i<=m;i++)
    36             scanf("%d",&c2[i]);
    37 
    38         for (i=1;i<=n;i++)
    39             f[i].reset();
    40 
    41         sort(c1+1,c1+n+1);
    42         sort(c2+1,c2+m+1);
    43         for (i=1;i<=n;i++)
    44             for (j=1;j<=m;j++)
    45                 if (0<=c1[i]+c2[j] && c1[i]+c2[j]<=w*2
    46                     && 0<=c1[i]-c2[j] && c1[i]-c2[j]<=h*2)  ///w*2 h*2 int range
    47                         f[i].set(j,1);
    48 
    49         sum=0;
    50         for (i=1;i<n;i++)
    51             for (j=i+1;j<=n;j++)
    52                 {
    53                     g=(f[i]&f[j]).count();
    54                     sum=(sum+1ll*g*(g-1)/2)%mod;
    55                 }
    56         printf("%lld
    ",sum); ///ll
    57     }
    58     return 0;
    59 }
    60 /*
    61 
    62 */

    6497 骑行

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e3+10;
    16 const int inf=1e9;
    17 const double eps=1e-8;
    18 
    19 double v,t;
    20 double w[maxn],s[maxn],a[maxn],lim[maxn];
    21 
    22 void work(double v1,double v2,double v0,double len,double a)
    23 {
    24     double dist=(v0*v0-v1*v1)/2/a + (v0*v0-v2*v2)/2/a;
    25     double dist1=(v2*v2-v1*v1)/2/a;
    26     if (dist<=len)
    27     {
    28         t+=(v0-v1)/a + (v0-v2)/a + (len-dist)/v0;
    29         v=v2;
    30     }
    31     else if (v2>v1 && dist1>len)
    32     {
    33         v=sqrt(2*a*len + v1*v1);
    34         t+=(v-v1)/a;
    35     }
    36     else
    37     {
    38         double v3=sqrt((2*a*len + v1*v1 + v2*v2)/2);
    39         t+=(v3-v1)/a + (v3-v2)/a;
    40         v=v2;
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     double temp;
    47     int T,n,i;
    48     scanf("%d",&T);
    49     while (T--)
    50     {
    51         scanf("%d",&n);
    52         for (i=1;i<=n;i++)
    53             scanf("%lf%lf%lf",&w[i],&s[i],&a[i]);
    54         lim[n]=s[n];
    55         for (i=n-1;i>=1;i--)
    56         {
    57             temp=sqrt(2*a[i+1]*w[i+1]+lim[i+1]*lim[i+1]);
    58             lim[i]=min(min(s[i],s[i+1]),temp);
    59         }
    60 
    61         v=0,t=0;
    62         for (i=1;i<=n;i++)
    63             work(v,lim[i],s[i],w[i],a[i]);
    64         printf("%.10f
    ",t);
    65     }
    66     return 0;
    67 }
    68 /*
    69 */

    6498 跨洋飞行

    一个点x到另外一个点y,到达点y时,要预留min(y to others)的油。参见题解。

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e3+10;
    16 const int inf=1e9;
    17 const double eps=1e-10;
    18 
    19 double x[maxn],y[maxn],dist[maxn],road[maxn][maxn],mr[maxn];
    20 bool vis[maxn];
    21 
    22 int main()
    23 {
    24     double a,b,c,d,u;
    25     int t,n,i,j,p;
    26     scanf("%d",&t);
    27     while (t--)
    28     {
    29         scanf("%d%lf%lf%lf%lf%lf",&n,&a,&b,&c,&d,&u);
    30         a+=b;
    31         for (i=1;i<=n;i++)
    32             scanf("%lf%lf",&x[i],&y[i]);
    33         for (i=1;i<=n;i++)
    34             mr[i]=1.0e18;
    35         for (i=1;i<n;i++)
    36             for (j=i+1;j<=n;j++)
    37             {
    38                 road[i][j]=road[j][i]=sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
    39                 mr[i]=min(mr[i],road[i][j]);
    40                 mr[j]=min(mr[j],road[i][j]);
    41             }
    42         mr[1]=0;    ///
    43         for (i=0;i<=n;i++)
    44             dist[i]=1.0e18;
    45         dist[1]=0;
    46         memset(vis,0,sizeof(vis));
    47         for (i=1;i<n;i++)
    48         {
    49             p=0;
    50             for (j=1;j<=n;j++)
    51                 if (!vis[j] && dist[p]>dist[j])
    52                     p=j;
    53             if (p==n)
    54                 break;
    55             vis[p]=1;
    56             for (j=1;j<=n;j++)
    57                 if (!vis[j] && mr[j]+road[p][j]<u+eps && dist[j]>dist[p] +a + road[p][j]*d + (mr[j]+road[p][j]-mr[p])*c)
    58                     dist[j]=dist[p] +a + road[p][j]*d + (mr[j]+road[p][j]-mr[p])*c;
    59         }
    60         printf("%.10f
    ",dist[n]);
    61     }
    62     return 0;
    63 }
    64 /*
    65 
    66 */

    错误想法:

    下界提高,x到y,至少dist(x,y)+min y to others(z)。而miny to others是有用的,x到y,剩余z,而y到其它点,至少要使用z,不浪费。除了最后一个点,浪费min n to others。但倒数第二个点到点n,而倒数第二个点到其它点的最短距离有可能不是该点到点n的距离。

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <iostream>
    11 using namespace std;
    12 
    13 #define ll long long
    14 
    15 const int maxn=1e3+10;
    16 const int inf=1e9;
    17 const double eps=1e-10;
    18 
    19 double x[maxn],y[maxn],dist[maxn],road[maxn][maxn],mr[maxn];
    20 bool vis[maxn];
    21 
    22 int main()
    23 {
    24     double a,b,c,d,u;
    25     int t,n,i,j,p;
    26     scanf("%d",&t);
    27     while (t--)
    28     {
    29         scanf("%d%lf%lf%lf%lf%lf",&n,&a,&b,&c,&d,&u);
    30         a+=b;
    31         for (i=1;i<=n;i++)
    32             scanf("%lf%lf",&x[i],&y[i]);
    33         for (i=1;i<=n;i++)
    34             mr[i]=1.0e18;
    35         for (i=1;i<n;i++)
    36             for (j=i+1;j<=n;j++)
    37             {
    38                 road[i][j]=road[j][i]=sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
    39                 mr[i]=min(mr[i],road[i][j]);
    40                 mr[j]=min(mr[j],road[i][j]);
    41             }
    42         for (i=1;i<=n;i++)
    43             for (j=1;j<=n;j++)
    44                 if (i!=j && road[i][j]+mr[i]>u+eps)
    45                     road[i][j]=-1;
    46                 else
    47                     road[i][j]=road[i][j]*(c+d)+a;
    48         for (i=0;i<=n;i++)
    49             dist[i]=1.0e18;
    50         dist[1]=0;
    51         memset(vis,0,sizeof(vis));
    52         for (i=1;i<n;i++)
    53         {
    54             p=0;
    55             for (j=1;j<=n;j++)
    56                 if (!vis[j] && dist[p]>dist[j])
    57                     p=j;
    58             if (p==n)
    59                 break;
    60             vis[p]=1;
    61             for (j=1;j<=n;j++)
    62                 if (!vis[j] && road[p][j]!=-1 && dist[j]>dist[p]+road[p][j])
    63                     dist[j]=dist[p]+road[p][j];
    64         }
    65         printf("%.10f
    ",dist[n]+mr[n]*c);
    66     }
    67     return 0;
    68 }
    69 /*
    70 
    71 */
  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/cmyg/p/10713800.html
Copyright © 2011-2022 走看看