走斜线

题目描述

   有天他来到一张方格地图上,整张地图可以看做一个二维坐标轴。牛牛此刻处于原点(0,0),他想要到点(x,y)去。牛牛有强迫症,他规定自己必须恰好k步走到点(x,y),中途可以经过任何点包括(x,y),但是第k步一定要到达(x,y)。
  一步有八种走法,直线东(+1,0)南(0,-1)西(-1,0)北(0,+1),斜线东南(+1,-1)东北(+1,+1)西南(-1,-1)西北(-1,+1)。牛牛会在能k步到达目的地的基础下尽量走斜线,你能计算出牛牛到底走了多少条斜线吗?

输入描述

  第一行一个整数T,代表数据组数。每组数据给出三个整数x,y,k。对于100%的数据,1<=T<=1000,
1<=x,y,k<=1000000000000000000。

输出描述

  对于每组数据,单独一行输出一个整数。如果牛牛可以在第k步的时候到达(x,y),输出牛牛走的斜线数量。如果牛牛不能到达,输出-1。

解题思路

  这道题感觉上和深搜类似,但实际差别很大,尤其是x,y,k的取值范围以及每一步的八个方向决定了搜索树相当大,因此深搜的方法不可靠。
  题目要求首先要能够在k步到达, 其次要求要尽量走斜线达到。关于是否能够在k步内到达,由于在地图上从(0,0)点开始行走,沿着斜线方向效率最高,比如沿着y=x这条线上所有点都是可以直接全部沿着斜线到达,并且至少需要x步,如果指定步数小于x,那么不可达。由此拓展,发现在x+y=2n的直线上的所有点都是可以完全通过走直线达到,并且可以发现达到这些点的最少步数为max(x,y)。对于这些完全通过斜线到达的点,如果指定步数大于需要的步数,那么剩余部分是偶数则这一部分完全可以通过走斜线消耗掉,是奇数则要用两条直线代替一条斜线(这部分画图就可以清楚)。
  对于那些不在上述线上的点,可以发现它的周围点都在这些线上,也就是说,走完斜线只需要再走一条直线就可以到达该点,达到该点的最小步数是周围点的最小步数加1。
  上述分析在画图的情况下十分清晰。

代码实现

#include <iostream>
using namespace std;
unsigned long long max(unsigned long long x,unsigned long long y){
	return x>y?x:y;
}
void getStep(unsigned long long x,unsigned long long y,unsigned long long k){
	unsigned long long minstep,remins;
    unsigned long long sum=x+y;
    unsigned long long result;
	if(sum%2==0){
		minstep=max(x,y);
		if(k<minstep)
			cout<<-1<<endl;
		else{
			remins=k-minstep;
			if(remins%2==0)
                cout<<k<<endl;     				
			else          
                cout<<k-2<<endl;       
		}
	}else{
		if(x>y)
			minstep=x-1;
		else
			minstep=y-1;
		if(k<minstep+1)
			cout<<-1<<endl;
		else
			cout<<k-1<<endl;
	}
	return;
}
int main(){
	unsigned long long t,x,y,k;
	cin>>t;
	while(t-->0){
		cin>>x>>y>>k;
		getStep(x,y,k);
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值