CF#305-C. Mike and Frog-数学模拟

本文介绍了一种通过枚举寻找两个数列中特定值相等的解决方案,利用循环节的概念来减少搜索次数,并讨论了算法中可能遇到的各种特殊情况。

给定x1,y1,x2,y2 ,m      

给定h1,h2

题意: 按照公式 h1=(h1*x1+y1)%m;     h2=(h2*x2+y2)%m;

经过t次变化,问你能否使得h1==a1;h2==a2;如果可以就输出t;否则输出-1

先在2*m次内枚举,前m次内求到第一次h1==a1,第二次求出循环节长度  (如果有)

如果得到st1==st2 (第一次满足h==a的起点),那么直接输出答案,

如果找不到起点,那么以后也不会找到了,输出-1;

要是都找到了起点和循环节,但是并不相同;

/*

如果h1和h2每次经过一个len1循环节后,相对的距离不变化,那么永远也不会相遇

如果他们相对距离靠近了哪怕是1,他们初始距离最大是m, 那么2*m次后,必定会相遇


*/

【这题好多坑】

1【有合法循环节但是开头几个数不一定在循环节内(即使 -1 5 7 开始循环(1 2...))】

2【没有包含a1 or a2循环节不一定输出-1(也许在前几次非循环节时就相等了)】

3【】

 

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

int main()
{
	__int64 mod,h1,h2,a1,a2,x1,x2,y1,y2;
	scanf("%I64d",&mod);
	scanf("%I64d%I64d",&h1,&a1); 
	scanf("%I64d%I64d",&x1,&y1);
	scanf("%I64d%I64d",&h2,&a2); 
	scanf("%I64d%I64d",&x2,&y2);
	__int64 i;
	__int64 st1,st2,len1,len2;
	st1=st2=len1=len2=-1;
	for (i=1;i<=2*mod;i++)	//如果h1能变到a1,那么走m步之内一定能达到。 并且2m步之内一定能找到第二次变成a1的点,从而得到循环节长度。
	{
		h1=(h1*x1+y1)%mod;
		if (h1==a1)
		{
			if (st1==-1)
				st1=i; //起点
			else
				if (len1==-1)
					len1=i-st1; //循环节长度
		}
		h2=(h2*x2+y2)%mod;
		if (h2==a2)
		{
			if (st2==-1)
				st2=i;
			else
				if (len2==-1)
					len2=i-st2;
		}
	}
	
	if (st1==-1||st2==-1)//m次都找不到起点,永远不可能找到起点了
		printf("-1\n");
	else
		if	(st1==st2)		//起点相同,ok
			printf("%I64d\n",st1);
		else		//分别找到了起点,但是不相等
		{
			for (i=1;i<=2*mod;i++)	//因为循环节最长是mod,所以如果答案存在 2*m次就找到了
			{
				if (st1<st2)
					st1+=len1;
				else
					if (st1>st2)
				 	st2+=len2;
					
					if(st1==st2)
					{
						printf("%I64d\n",st1 );  
						return 0;
					}
			}
			printf("-1\n");
		}  
		return 0;
		
}


A player wants to press the direction buttons as little as possible so that both frogs arrive at the destination to finish the game. Find the minimum number of times the player pressed the buttons to finish the game. If the frog or green frog cannot arrive at the destination, output -1. [Figure] For example, let's look at the case where a grid with six rows and six columns is given. The frog is located at (6, 1), the green frog is located at (1, 6), and the destination is (2, 3) as shown in the [Figure]. Walls are marked with #. First, the frog arrives at the destination first by moving eight times as shown on the left side of the [Figure], and the green frog moves to the opposite direction at the same time and is located at (6, 4). Next, as shown on the right side of the [Figure], when the green frog arrives at the destination by moving it five times, you pressed the buttons 13 times for both frogs to arrive at the destination. This is the minimum number of times you press the buttons. [Constraints] 1. N and M are integers from 2 to 40. 2. R1, R2, and R3 are integers from 1 to N. 3. C1, C2, and R3 are integers from 1 to M. 4. Both frogs cannot be at the same location while they are moving. 5. Walls are not the start and destination of both frogs, and the start positions of the two frogs are not their destinations. [Input] First, the number T of test cases is given, followed by T test cases. On the first line of each test case, N and M are given, separated by spaces. On the next line, R1, C1, R2, C2, R3, and C3 are given in the order, separated by spaces. Over the next N lines, a string of length M is given..” represents a position in the grid to which both frogs can move, and “#” represents a wall. [Output] Output one line per test case. For each test case, output “#x” (where x is the number of the test case, starting from 1), leave a space, and then output the answer of the relevant test case. [Example of Input and Output] (Input) 1 6 6 6 1 1 6 2 3 ....#. .#..#. .#..#. .#..#. .#.##. .#....
最新发布
09-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值