[分类] Jzoj P1320 拯救奶牛
题解
- 把原三角形旋转一下,看成三个三角形,顶部分别是原三角形最上、最左下和最右下的三个小三角
- 于原三角形的侧着走,相当于在另两个三角形中的横着走,那么记录一个点分别在三个三角形中的行数,最小步数即为三个绝对值的和
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int n,m,ans,r; 8 struct node {int x,y;}p,q,mn; 9 int work(node p,node q) 10 { 11 int l,r,sum=0,x=abs(p.x-q.x); 12 if (!x) return abs(p.y-q.y); 13 sum+=x*2-(q.y&1); 14 if (q.y&1) l=q.y+1,r=l+(x-1)*2; else l=q.y,r=l+x*2; 15 if (l<=p.y&&p.y<=r) sum+=(p.y&1); 16 else 17 { 18 if (abs(p.y-l)<abs(p.y-r)) sum+=abs(p.y-l); else sum+=abs(p.y-r); 19 } 20 return sum; 21 } 22 int main() 23 { 24 scanf("%d%d%d%d",&n,&m,&p.x,&p.y),ans=0x7fffffff; 25 for (int i=1;i<=m;i++) 26 { 27 scanf("%d%d",&q.x,&q.y); 28 if (!(q.y<=q.x*2-1&&1<=q.x&&q.x<=n)) continue; 29 if (q.x>p.x) r=work(q,p); else r=work(p,q); 30 if (r+1<ans) ans=r+1,mn=q; 31 } 32 printf("%d %d\n%d",mn.x,mn.y,ans); 33 }