A. Maomao's candy

原题链接:https://nanti.jisuanke.com/t/41407
在这里插入图片描述
日常补题,ACM群大佬发的题解我只是实现代码没什么创新,哀叹啊。。看着思路写代码都实现的n次才对。。我真辣鸡!我真辣鸡!我真辣鸡!错误总结:变量类型声明要一致!要一致!要一致!
AC代码:

#include <bits/stdc++.h>
using namespace std;


typedef long long ll;
ll n, m; 
const int mod = 1025436931;
const int maxn = 2;
int len;

struct Matrix
{
	ll matrix[maxn][maxn];
	
	Matrix(int n)
	{
		memset(matrix, 0, sizeof(matrix));
		if (n)
		{
			for (int i = 0; i < len; ++i)
				matrix[i][i] = 1;
		}
	}
	
	void con(ll *num)
	{
		for (int i = 0; i < len; ++i)
			for (int j = 0; j < len; ++j)
				matrix[i][j] = num[i*len + j];
	}
	
	Matrix(const Matrix &a)
	{
		for (int i = 0; i < len; ++i)
			for (int j = 0; j < len; ++j)
				matrix[i][j] = a.matrix[i][j];
	}
	
	Matrix operator * (const Matrix& b) const
	{
		Matrix c(0);
		for (int i = 0; i < len; ++i)
			for (int j = 0; j < len; ++j)
				for (int k = 0; k < len; ++k)
				{
					c.matrix[i][j] += (matrix[i][k] * b.matrix[k][j]) % mod;
					c.matrix[i][j] %= mod;
				}
		return c;
	}
	
	Matrix& operator *= (const Matrix& b) {return *this = *this * b;}
};

Matrix mapow(const Matrix &a, const ll n)
{
	Matrix val(a), mul(1);
	ll v = n;
	while (v)
	{
		if (v & 1)
			mul *= val;
		val *= val;
		v >>= 1;
	}
	return mul;
}

Matrix mat(0);
// 1 1000000000 1000000000 1 1 1000000000 1000000000
ll solve(ll n)
{
	len = 2;
	ll a[] = {1, 1, 1, 0};
	mat.con(a);
	Matrix ans(0);
	if (n > 2)
		ans = mapow(mat, n - len);
	else if (n == 1)
		ans.matrix[0][1] = 1;
	else
		ans.matrix[0][0] = 1;
	return (3 * ans.matrix[0][0] % mod + 2 * ans.matrix[0][1] % mod - 1 + mod) % mod;
}

int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		ll r1, r2, c1, c2, step;
		scanf("%lld %lld %lld %lld %lld %lld", &n, &m, &r1, &c1, &r2, &c2);
		if (min(n, m) < 2)
		{
			if (r1 == r2)
			{
				if (c1 > c2)
					step = (c1 - c2) & 1 ? c1 - 1 : c1 - 2;
				else
					step = (c2 - c1) & 1 ? m - c1 : m - c1 - 1;
			}	
			else
			{
				if (r1 > r2)
					step = (r1 - r2) & 1 ? r1 - 1 : r1 - 2;
				else
					step = (r2 - r1) & 1 ? n - r1 : n - r1 - 1;
			}
		}
		else
		{
			if ((abs(r1 - r2) + abs(c1 - c2)) & 1)
				step = 0;
			else
			{
				int zs = r1 + c1 - 3;
				int zx = n - r1 + c1 - 2;
				int ys = r1 - 2 + m - c1;
				int yx = n + m - r1 - c1 - 1;
				if (abs(r1 - r2) == abs(c1 - c2))
				{
					if (r2 < r1 && c2 < c1) // 左上角 
						step = zs;
					else if (r2 > r1 && c2 < c1) // 左下角 
						step = zx;
					else if (r2 < r1 && c2 > c1) // 右上角
						step = ys;
					else // 右下角 
						step = yx;
				}
				else if (abs(r1 - r2) < abs(c1 - c2)) // 左右 
				{
					if (c2 < c1) // 左 
						step = max(zs, zx);
					else // 右 
						step = max(ys, yx);
				}
				else // 上下 
				{
					if (r2 < r1) // 上
						step = max(zs, ys);
					else
						step = max(zx, yx); 
				}
			}
		}
		if (step)
			printf("%lld\n", solve(step));
		else
			puts("countless");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值