poj 1654 && poj 1675

先说一下叉积求面积

View Code
 1 struct node
 2 {
 3     int x;
 4     int y;
 5 }point[N];  // 数组保存多边形顶点,但是必须按顺序(逆或顺)保存
 6 double area(int n)  // n 表示多边形的顶点数
 7 {
 8     int i;
 9     double a = 0;
10     for(i = 0; i < n; i++)
11     {
12         int j = (i + 1) % n; // 保证最后一个和第一个连起来
13         a += point[i].x * point[j].y - point[i].y * point[j].x;
14     }
15     if(a < 0) a = -a;  // 注意叉积求出来的面积可能为负
16     return (a / 2);
17 }

然后下面的题目是相当简单的

题目:http://poj.org/problem?id=1654

View Code
 1 typedef long long ll;
 2 const int inf = 100000007;
 3 const double pi = sqrt(3.0) / 2.0;
 4 const double eps = 1e-8;
 5 int area[10][2] = {{0,0},{1,-1},{1,0},{1,1},{0,-1},{0,0},{0,1},{-1,-1},{-1,0},{-1,1}};
 6 int main()
 7 {
 8     ll ans;
 9     int t;
10     char ch;
11     scanf("%d",&t);
12     getchar();
13     while(t--)
14     {
15         int x1 = 0, y1 = 0;
16         ans = 0;
17         while(scanf("%c",&ch),ch != '5')
18         {
19             int x2 = area[ch - '0'][0] + x1;
20             int y2 = area[ch - '0'][1] + y1;
21             ans += x1 * y2 - y1 * x2;
22             x1 = x2, y1 = y2;
23         }
24         if(ans < 0) ans = -ans;
25         if(ans % 2) printf("%.1lf\n",(double)(ans) / 2);
26         else printf("%I64d\n",ans / 2);
27     }
28     return 0;
29 }

题目:http://poj.org/problem?id=1675

题意:给三个点在蛋糕上,问是否可以把蛋糕平分成三份而且每一份上有一个点

View Code
 1 typedef long long ll;
 2 const int inf = 100000007;
 3 const double pi = acos(-1.0);
 4 const double eps = 1e-8;
 5 int x[3],y[3],r;
 6 int pows(int x)
 7 {
 8     return x * x;
 9 }
10 double geta(double x1,double y1,double x2,double y2)
11 {
12     double a = acos((pows(x1) + pows(y1) + pows(x2) + pows(y2) - pows(x1 - x2) - pows(y1 - y2)) / (2 * sqrt((double)(pows(x1) + pows(y1))) * sqrt((double)(pows(x2) + pows(y2)))));  // 根据余弦定理求cos值
13     return a * 180.0 / pi;  // 算出角度
14 }
15 bool juge()
16 {
17     int i,j,k;
18     double a1,a2;
19     for(i = 0; i < 3; i++)
20     {
21         int temp = 0;
22         j = (i + 1) % 3, k = (i + 2) % 3;
23         a1 = geta(x[0],y[0],x[j],y[j]);
24         a2 = geta(x[j],y[j],x[k],y[k]);
25         temp = int(a1 == 120.0) + int(a2 == 120.0);  // 题目保证了三个点都在园上,所以如果两个角都是 120,那么肯定可以
26         if(temp == 2) return true;
27         if(a1 > 120.0 && a2 > 120.0) continue;  // 如果两个都大于 120,继续判断
28         if(a1 < 120.0 && a2 < 120.0) continue; // 同理
29         if(a1 != 0.0 && a2 != 0.0) return true;  // 两个交都不同时大于 120 也不小于 120,也不为零,那么肯定可以
30     }
31     return false;
32 }
33 int main()
34 {
35     //freopen("data.txt","r",stdin);
36     int i,t;
37     scanf("%d",&t);
38     while(t--)
39     {
40         scanf("%d%d%d%d%d%d%d",&r,&x[0],&y[0],&x[1],&y[1],&x[2],&y[2]);
41         int flag = 0;
42         for(i = 0; i < 3; i++)
43         if(x[i] == 0 && y[i] == 0)  // 如果有某个点在中心,那么一定不可以
44         {
45             flag = 1;
46             break;
47         }
48         if(!flag && juge()) printf("Yes\n");
49         else printf("No\n");
50     }
51     return 0;
52 }

转载于:https://www.cnblogs.com/fxh19911107/archive/2012/08/20/2648134.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值