zju-1606

IAmWaistcoat 2003-06-08 01:13:12
谈谈思路吧,由程序更好

http://acm.zju.edu.cn/show_problem.php?pid=1606

----------------------------------------------------------------------

An unbounded triangular grid is a plane covered by equilateral triangles:



Two neighboring triangles in the grid form a rhomb. There are 3 types of such rhombs:



A grid polygon is a simple polygon which sides consist entirely of sides of triangles in the grid. We say that a grid polygon is rhombastic if it can be partitioned into internally disjoint rhombs of types A, B and C.

As an example let's consider the following grid hexagon:



This hexagon can be partitioned into 4 rhombs of type A, 4 rhombs of type B and 4 rhombs of type C:



For a given rhombastic grid polygon P compute the numbers of rhombs of types A, B and C in some correct partition.

Write a program that:

> reads a description of a rhombastic grid polygon from the standard input,

> computes the numbers of rhombs of types A, B and C in some correct partition of the polygon,

> writes the results to the standard output.


Input

The first line of the input contains an integer n (3 <= n <= 50 000) - the number of sides of a rhombastic grid polygon. Each of the next n lines contains a description of one side of the polygon. The sides are given one by one in the clockwise order. No two consecutive sides of the polygon lie on the same straight line. The description of a side consists of two integers d and k. Integer d says what is the direction of the side according to the following figure:




Integer k is the length of the polygon side measured in the number of sides of grid triangles. Sum of all numbers k is not larger than 100 000.

Process to the end of file.


Output

The first and only line of the output contains three integers separated by single spaces denoting the number of rhombs of type A, B and C respectively, in some partition of the input polygon.


Sample Input

6
1 2
2 2
3 2
4 2
5 2
6 2


Sample Output

4 4 4
...全文
82 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
IAmWaistcoat 2003-06-18
  • 打赏
  • 举报
回复
这么久了,我以为从此石沉大海,幸好有各位热心参与,谢谢。尤其是alongzju(alongzju),你的绝对是正解

揭帖
lymgf 2003-06-18
  • 打赏
  • 举报
回复
楼上的很厉害,不知有没有更简单的
alongzju 2003-06-18
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>
using namespace std;

int main()
{
int a,b,c,i,n,d,x;
int sa,sb,sc;
while(cin >> n)
{
sa=sb=sc=a=b=c=0;
for(i=0;i<n;i++)
{
cin >> d >> x;
switch(d)
{
case 1:
b+=x; c-=x; sa-=a*x;
break;
case 2:
a+=x; b+=x; sc-=c*x;
break;
case 3:
a+=x; c+=x; sb+=b*x;
break;
case 4:
b-=x; c+=x; sa+=a*x;
break;
case 5:
a-=x; b-=x; sc+=c*x;
break;
case 6:
a-=x; c-=x; sb-=b*x;
break;
}
}
if (sa < 0) sa*=-1;
if (sb < 0) sb*=-1;
if (sc < 0) sc*=-1;
cout << (sb+sc-sa)/2 << ' ' << (sa+sc-sb)/2 << ' ' << (sa+sb-sc)/2 << endl;
}
}
HUNTON 2003-06-18
  • 打赏
  • 举报
回复
强烈反对题目用英文的,这里又不是英文版的。
lymgf 2003-06-18
  • 打赏
  • 举报
回复
刚刚做出来,程序有点长,搂住自己慢慢看吧。
不过我很想知道312k,0.05s做出来的牛人是如何解决这题的?难道输入数据不用存储?

#include <stdio.h>

struct SIDE
{
int dir; //方向
int len; //长度
int pre; //前接邻边
int next; //后接邻边
};

SIDE sides[50000];

int type[][7]={{ 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 3, 5,-1, 4, 6},
{ 0, 4, 0, 1, 3,-1, 2},
{ 0, 6, 2, 0, 5, 1,-1},
{ 0,-1, 4, 6, 0, 3, 5},
{ 0, 3,-1, 2, 4, 0, 1},
{ 0, 5, 1,-1, 6, 2, 0}};

int main()
{
int n;
int a,b,c,i;
int cur1,cur2,temp;
bool bRemoved;

while(scanf("%d",&n)!=EOF)
{
for (i=0;i<n;i++)
{
scanf("%d %d",&sides[i].dir,&sides[i].len);
sides[i].pre =i-1;
sides[i].next=i+1;
}
sides[0].pre=n-1;
sides[n-1].next=0;
a=b=c=0;
cur1=0,cur2=1;
while(n>0)
{
bRemoved=false;
//按平行四边形计算面积
switch(type[sides[cur1].dir][sides[cur2].dir])
{
case 1: //+A型
a+=sides[cur1].len*sides[cur2].len;
break;

case 2: //-A型
a-=sides[cur1].len*sides[cur2].len;
break;

case 3: //+B型
b+=sides[cur1].len*sides[cur2].len;
break;

case 4: //-B型
b-=sides[cur1].len*sides[cur2].len;
break;

case 5: //+C型
c+=sides[cur1].len*sides[cur2].len;
break;

case 6: //-C型
c-=sides[cur1].len*sides[cur2].len;
break;
}

//交换两线段的矢量值
temp=sides[cur1].dir;
sides[cur1].dir=sides[cur2].dir;
sides[cur2].dir=temp;
temp=sides[cur1].len;
sides[cur1].len=sides[cur2].len;
sides[cur2].len=temp;

//合并共线的线段
//cur1是否与前接邻边共线
if (sides[cur1].dir==sides[sides[cur1].pre].dir)
{
cur1=sides[cur1].pre;
sides[cur1].len+=sides[sides[cur1].next].len;
n--;
}
else if (type[sides[cur1].dir][sides[sides[cur1].pre].dir]==-1)
{
n--;
cur1=sides[cur1].pre;
sides[cur1].len-=sides[sides[cur1].next].len;
if (!sides[cur1].len)
{
cur1=sides[cur1].pre;
bRemoved=true;
n--;
}
else if (sides[cur1].len<0)
{
sides[cur1].dir=sides[sides[cur1].next].dir;
sides[cur1].len=-sides[cur1].len;
}
}

//cur2是否与后接邻边共线
if (sides[cur2].dir==sides[sides[cur2].next].dir)
{
cur2=sides[cur2].next;
sides[cur2].len+=sides[sides[cur2].pre].len;
n--;
}
else if (type[sides[cur2].dir][sides[sides[cur2].next].dir]==-1)
{
n--;
cur2=sides[cur2].next;
sides[cur2].len-=sides[sides[cur2].pre].len;
if (!sides[cur2].len)
{
cur2=sides[cur2].next;
bRemoved=true;
n--;
}
else if (sides[cur2].len<0)
{
sides[cur2].dir=sides[sides[cur2].pre].dir;
sides[cur2].len=-sides[cur2].len;
}
}

//cur2与cur是否共线
if (bRemoved)
{
if (sides[cur2].dir==sides[cur1].dir)
{
sides[cur1].len+=sides[cur2].len;
cur2=sides[cur2].next;
n--;
}
else
while (n>0 && type[sides[cur2].dir][sides[cur1].dir]==-1)
{
n--;
sides[cur1].len-=sides[cur2].len;
if (!sides[cur1].len)
{
cur1=sides[cur1].pre;
n--;
}
else if (sides[cur1].len<0)
{
sides[cur1].dir=sides[cur2].dir;
sides[cur1].len=-sides[cur1].len;
}
cur2=sides[cur2].next;
}
}

sides[cur1].next=cur2;
sides[cur2].pre=cur1;
cur1=cur2;
cur2=sides[cur2].next;
}

printf("%d %d %d\n",a,b,c);
}
}
IAmWaistcoat 2003-06-08
  • 打赏
  • 举报
回复
楼上的不要开这种玩笑

希望大家解答,UP
Turing_0 2003-06-08
  • 打赏
  • 举报
回复
既然你是马家,就等你的主人来回答吧。

33,009

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧