zoukankan      html  css  js  c++  java
  • uva 10641 (来当雷锋的这回....)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    
    int n,m;
    int f[100];
    struct point{
        double x,y;
        point(double xx = 0,double yy = 0){
            this->x = xx;
            this->y = yy;
        }
        void read(){
            scanf("%lf%lf",&x,&y);
        }
    }p[100];
    struct Q{
        int l,r,c;
    }q[1005];
    bool judge(point pp,point p1,point p2){///向量叉积。推断顺逆时针时注意三个点的先后位置
        /// <0是就是第一个向量在第二个向量的逆时针方向;
        return ((p1.x-pp.x)*(p2.y-pp.y)-(p2.x-pp.x)*(p1.y - pp.y)) < -eps;
    }
    Q tra(point t,int c){
        Q ans;
        bool flag[100];
        memset(flag,false,sizeof(flag));
        for(int i = 0; i < n; i++){
            if(judge(t,p[i],p[i+1])){///推断能不能照到这条边
                                     ///(实际上推断转化成了照到点);
                flag[i] = true;
            }
        }
        ///以下是处理得出的数据,保存下每一个灯所能照到的最左端和最右端;
        if(flag[n-1]&&flag[0]){
            int left = n-1;
            while(flag[left-1]){left--;}
            int right = 0;
            while(flag[right+1]){right++;}
            ans.l = left;
            ans.r = right + n;
        }
        else{
            int left = 0,right = n-1;
            while(!flag[left]){left++;}
            while(!flag[right]){right--;}
            ans.l = left;
            ans.r = right;
        }
        ans.c = c;
        return ans;
    }
    bool solve()
    {
        int ans = inf;
        for(int i = 0; i < n; i++){
            memset(f,inf,sizeof(f));
            f[i] = 0;
            for(int j = 0; j < n; j++){
                int r = i + j;///从第i个点開始往后数了j个;
                              ///多定义这么一个层次,能够使状态的转移变得有序
                for(int k = 0; k < m; k++){
                    if(q[k].l > r) continue;///当前点与该灯照亮的最左点之间有空隔,就不符合開始更新的条件;
                    if(q[k].r < r) continue;///这是个剪枝,去掉也对;就是不再考虑不会成为最优解的情况;
                    int now = min(q[k].r + 1, i + n);///依据区间右端点往后更新。可是一旦更新过了i+n就要将端点定为i+n;
                    f[now] = min(f[now],f[r] + q[k].c);
                }
            }
            ans = min(ans,f[i+n]);
        }
        if(ans == inf) return false;
        printf("%d
    ",ans);
        return true;
    }
    int main()
    {
        while(scanf("%d",&n) != EOF){
            if(n == 0) break;
            for(int i = 0; i < n; i++){
                p[i].read();
            }
            p[n] = p[0];
    
            scanf("%d",&m);
            point temp;int c;
            for(int i = 0; i < m; i++){
                temp.read();
                scanf("%d",&c);
                q[i] = tra(temp,c);
            }
    
            if(!solve()) printf("Impossible.
    ");
        }
        return 0;
    }
    

  • 相关阅读:
    【Statistics】均值
    【Datastage】在win10安装Datastge 8.7
    【Linux】行首、行尾添加字符串
    【Linux】替换文本中的字符
    【Pyhton 数据分析】通过gensim进行文本相似度分析
    【Python 数据分析】jieba文本挖掘
    异或运算法则
    关于计算机中的《补码》,公式:-n=~n+1 引伸:~n=-n-1
    Base64编码解码
    位运算之——按位与(&)操作——(快速取模算法)
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7020310.html
Copyright © 2011-2022 走看看