Problem-2036 改革春风吹满地(java)

这里写图片描述


我认为这道题有三个难点:

1.怎样更加简便的实现点的存取,我们可以将点设计成一个类;
2.怎样算多边形的面积,我采用的是海伦公式;
这里写图片描述
3.一般人都会想到将多边形分成三角形来将面积求和,这里的难点就是要注意这并不是一个规则的多边形,所以要考虑多边形的凹凸性,我采用了判断斜率大小的方法来判断当前所计算的三角形的面积是否是多边形的一部分,即判断它的凹凸性。

修改多次,最终AC了,新手所以代码不够简洁。

import java.util.*;
public class Main {

    public static  void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext())
        {
            int n=sc.nextInt();
            if(n==0)
            {
                break;
            }
            if(n>=3 && n<=100)//不要忘记题目对n的限定条件
            {
            List<P> a=new ArrayList<P>();
            for(int i=0;i<n;i++)
            {
                double x=sc.nextDouble();
                double y=sc.nextDouble();
                a.add(new P(x,y));//将点这个对象存进去
            }
            double ans = 0;
            for(int i=1; i<n-1; i++) {
                double x=a.get(i).sub(a.get(0));//最初点和第i-1个点的连线长度
                double y=a.get(i+1).sub(a.get(0));//最初点和第i个点的连线长度
                double z=a.get(i).sub(a.get(i+1));//第i-1个和第i个点的连线长度
                double s=(x+y+z)/2;//三角形的半周长
                double q=Math.sqrt(s*(s-x)*(s-y)*(s-z));//海伦公式
                if(a.get(0).juge(a.get(i), a.get(i+1))==1)//判断凹凸性
                {
                    ans += q;//若为凸则加上这个三角形的面积
                }
                else
                {
                    ans-=q;//若为凹则减去这个三角形的面积
                    //之所以要减去是因为计算下一个为凸的三角形的面积时会将这个三角形的面积包括进去,可以自己举个例子画个图就很清楚了
                }

            }
            System.out.printf("%.1frn", ans );//按照格式输出
            }
        }
        sc.close();
    }

}
class P
{
    double x;
    double y;
    public P(double x,double y)
    {
        this.x=x;
        this.y=y;
    }
    public double sub(P p) {
        // 求当前点和指定点的连线长度
        double m=this.x-p.x;
        double n=this.y-p.y;
        double s= Math.sqrt(m*m+n*n);
        return s;
    }
    public int juge(P p,P m)
    {
    //求当前点和另外两点所组成的三角形的凹凸
        double k=(this.y-p.y)/(this.x-p.x);
        double g=(m.y-this.y)/(m.x-this.x);
        if(k<=g)
        {
            return 1;
        }
        else
        {
            return -1;
        }

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The 0-1 Knapsack Problem is a classic optimization problem in computer science and mathematics. The problem is as follows: Given a set of items, each with a weight and a value, determine the items to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. The 0-1 indicates that each item can only be included once or not at all. This problem can be solved using dynamic programming. We can create a two-dimensional array where the rows represent the items and the columns represent the weight limit. For each item and weight limit, we can calculate the maximum value that can be obtained by either including the item or excluding it. We can then fill in the array row by row until we reach the final row, which represents the optimal solution. Here is an example implementation of the 0-1 Knapsack Problem in Java: ``` public class Knapsack { public static int knapsack(int[] values, int[] weights, int limit) { int[][] dp = new int[values.length + 1][limit + 1]; for (int i = 1; i <= values.length; i++) { for (int j = 1; j <= limit; j++) { if (weights[i-1] > j) { dp[i][j] = dp[i-1][j]; } else { dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weights[i-1]] + values[i-1]); } } } return dp[values.length][limit]; } public static void main(String[] args) { int[] values = {60, 100, 120}; int[] weights = {10, 20, 30}; int limit = 50; int result = knapsack(values, weights, limit); System.out.println("Maximum value: " + result); } } ``` In this example, we have three items with values of 60, 100, and 120 and weights of 10, 20, and 30, respectively. We want to find the maximum value we can obtain with a weight limit of 50. The result is 220, which indicates that we should select items 2 and 3 to maximize the value while staying under the weight limit.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值