poj 1925 Spidermax 夜

http://poj.org/problem?id=1925

蜘蛛侠要从最左荡到最右

荡的过程中不能着地 问最少荡多少次

荡点 在荡的过程中高度不变

要以 荡点(0...1000000)找最小答案进行更新

代码及其注释:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<stack>
#include<algorithm>

using namespace std;
const int N=5005;
int X[N];//建筑的x坐标
int H[N];//建筑的高度
int ans;//最终答案
int num[1000005];//x处的点 要想荡到这里 最少多少次
int n;
int findlx(int h)//高度为 h 是可由左边 多少范围内的点 往这荡
{
    double x=(double)abs(H[0]-h);
    double z=(double)h;
    return int(z*cos(asin(x/z)));

}
int main()
{
   int K;
   scanf("%d",&K);
   while(K--)
   {
       scanf("%d",&n);
       for(int i=0;i<n;++i)
       {
           scanf("%d %d",&X[i],&H[i]);
       }
       ans=N;
       memset(num,-1,sizeof(num));//初始化
       num[X[0]]=0;//起点 荡 0 次
       for(int i=1;i<n;++i)
       {
           int lx=X[i]-findlx(H[i]);//向左偏移
           for(int j=max(X[0],lx);j<X[i];++j)//遍历
           {
               if(num[j]!=-1)//左边点 有可能
               {
                   if(X[i]+X[i]-j>=X[n-1])//更新答案
                   {
                       ans=min(ans,num[j]+1);
                       continue;
                   }
                   if(num[X[i]+X[i]-j]==-1||num[X[i]+X[i]-j]>num[j]+1)//更新右边的点
                   {
                       num[X[i]+X[i]-j]=num[j]+1;
                   }
               }
           }
       }
       if(ans==N)
       printf("-1\n");
       else
       printf("%d\n",ans);
   }
   return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2599972.html