一道很难的数学题!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道很难的数学题!相关的知识,希望对你有一定的参考价值。

某2000边形的顶点按顺时针依次编号为1、2、3、......2000。大小两只电子青蛙在这些顶点上跳动,他们都是同时开始起跳,开始的时候,大青蛙在1号顶点,之后每秒顺时针跳过189个顶点(例如从1到191顶点);小青蛙在121顶点,之后每秒逆时针跳过89个顶点。若连续条二十四小时则两只青蛙多少次跳入同一个顶点?有哪些编号的顶点曾经被2只青蛙同时跳入?

答:共864次。大青蛙在1号顶点,之后每秒顺时针跳过189个顶点,即走动了190格(例如从1到191顶点);小青蛙在121顶点,之后每秒逆时针跳过89个顶点,即走动了90格(121-89-1=31点)。最初未跳时大青蛙为1,小青蛙为121,即相差120,如果两青蛙跳动格数之和为2000m+120,则他们同时跳入一个顶点。第n秒他们共跳了(190n+90n)=280n格,所以:
280n=2000m+120
m=0.14n-0.06
其中:m为整数,代表圈数,即两青蛙跳过的边数(格数)之和为m圈多120时,二者跳到同一个顶点。n为秒数,从1到86400的整数。
将1,2,3,4,5................86400秒分别代入上式,m为整数的情况是:
(1)在excel表的列的第一格A1填入“1”,在A列的第二格“A2中”写入公式:“=A1+1”,再从A2一直向下拖动鼠标,直到86400;
在第二列B1处写入公式“=0.14*40*A1-0.06”,一直向下拖到B86400;
在第三列C1处写入公式“=int(B1)”,一起拖到C86400;
再在第D1处写入公式“=B1-C1”一直拖动鼠标到D86400;
再在E列的E1写入:=IF(C1>D1,0,1),拖动鼠标到E86400
再在E列数字仍为选中时,点击求和的符号:“Σ”,得到的和,即为同时跳入一个顶点的数目。
(2)在上述操作过程中,发现第29次(秒)时,m=4,
以后,再增加100,如129秒,则增加14,此时,m=18
而一天一晚24小时为86400秒,故包含有864个以29结尾的数字,因此24小时内,两青蛙跳入同一个顶点的次数为:864次。
pxwu
参考技术A 大的跳的顶点编号为:1+190N,如果得数大于2000则为该结果减去2000;
小的跳的顶点编号为:121-90N,如果得数小于0则将结果加上2000。
首先计算第一个交会点。可以发现上述两个表达式只要在N相等时相差为2000的整数倍就是交汇点,所以:
(1+190N)-(121-90N)=280N-120=2000k,k=1,2,3......
可以算出满足条件的第一个点对应k=4,N=29,所以经过29秒后二者同时跳入:
1+190×29=5511或者121-90×29=-2489【换算结果为:1511顶点】
然后二者又同时出发,下一次的交会点为:k=11,N=79,在第79秒二者同时跳入:
1+190×79=15011或者121-90×79=-6989【换算结果为:1011顶点】
很显然,此后的过程具有这样的规律,每次的交会点都是经过50秒二者同时跳入当前顶点减去500的点(当小于0时加上2000)。
那么二十四小时共有86400秒,而交汇时间满足29+50M的公式。解不等式:
29+50M≤86400
解得:M≤1727.42
所以总共二者同时跳入一个顶点的次数为:1+1727=1728【前面加1表示第29秒的交会】
而这些顶点的编号为:1511,1011,511,11。
参考技术B 这个数据量太大了 要用编程计算来做 麻烦

1、控制变量2000(跳过顶点和落入点) ,这两点都要注意,步长不一样啊
2、时间太长,86400 秒 有点太长
参考技术C 太难了追问

世上无难事,只要肯登攀!此题虽难,但是有志者,事竟成!

本回答被提问者采纳
参考技术D 好麻烦啊。。。。

迷宫广搜

上学期学了C,这学期学C++。感觉最难的还是算法,上周作业的一道广搜题是我第一次接触广搜,由于第一学期刚学编程就接触的太多的算法难题,不禁对代码产生畏惧,不过还好没有放弃,虽然算法很难,但我慢慢找到了一点学数学时的乐趣。
先介绍一下这道未来的我看过来会觉得很简单一道题吧
技术分享
You are provided a maze(迷宫), and you need to program to find the least steps to walk from the start to the end.And you can only walk in four directions:up, down,left, right.
There will only be 5 kinds of characters in the maze.The meaning of each is as followed.
‘#‘ is for rock, which you can not walk through.
‘S‘ is for start.
‘E‘ is for end.
‘.‘ is for road.
‘!‘ is for magma(岩浆),which you can not walk through.
Input
n,m represent the maze is a nxm maze.(n rows, m columnsm,0 <= 21).
Then is the maze.
e.g.
55
#####
#S..#
#.!.#
#.#E#
#####
Output
You need to give the least steps to walk from start to the end.If it doesn‘t e xist, then output -1.
e.g.(for the example in input)
4

任性的我一开始没有按照hint去找广搜,因为以前做过一道深搜题也是关于迷宫的,于是一开始我就按照深搜的方法去找最短路径
------有些地方有错,由于从我的新浪博客上搬运过来的,不知道为什么会变成这个样子~_~
#include
#include
#include
using namespace std;
int least_step(char (*p)[21], int n, int m);//深搜寻找最短路径
int main() {
	int n, m;
	char maze[21][21];
	for (int i = 0; i < 21; i++) {
		for (int j = 0; j < 21; j++) {
			maze[i][j] = ‘#‘;
		}
	}//初始化迷宫格子
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> maze[i][j];
		}
	}
	cout << least_step(maze, n, m) << endl;
	return 0;
}
int least_step(char (*p)[21], int n, int m) {
	static int len = 0;
	static priority_queue, greater > len_s;//存储路径.
	int i, j;
	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (p[i][j]== ‘S‘)
				break;
		}
		if (p[i][j] == ‘S‘)
			break;
	}
	if (p[i + 1][j] == ‘E‘ && i + 1 < n) {
		len++; len_s.push(len); len--; return 1;
	}
	else if (p[i][j + 1] == ‘E‘ && j + 1 < m) {
		len++; len_s.push(len); len--; return 1;
	}
	else if (p[i][j - 1] == ‘E‘ && j - 1 > 0) {
		len++; len_s.push(len); len--; return 1;
	}
	else if (p[i - 1][j] == ‘E‘ && i - 1 > 0) {
		len++; len_s.push(len); len--; return 1;
	}//如果找到了终点就返回
	if (p[i + 1][j] == ‘.‘ && i + 1 < n) {
		p[i][j] = ‘#‘;
		p[i + 1][j] = ‘S‘;
		len++;
		least_step(p, n, m);
		p[i][j] = ‘S‘;
		p[i + 1][j] = ‘.‘;
		len--;
	}
	if (p[i][j + 1] == ‘.‘ && j + 1 < m) {
		p[i][j] = ‘#‘;
		p[i][j + 1] = ‘S‘;
		len++;
		least_step(p, n, m);
		p[i][j] = ‘S‘;
		p[i][j + 1] = ‘.‘;
		len--;
	}
	if (p[i][j - 1] == ‘.‘ && j - 1 > 0) {
		p[i][j] = ‘#‘;
		p[i][j - 1] = ‘S‘;
		len++;
		least_step(p, n, m);
		p[i][j] = ‘S‘;
		p[i][j - 1] = ‘.‘;
		len--;
	}
	if (p[i - 1][j] == ‘.‘ && i - 1 > 0) {
		p[i][j] = ‘#‘;
		p[i - 1][j] = ‘S‘;
		len++;
		least_step(p, n, m);
		p[i][j] = ‘S‘;
		p[i - 1][j] = ‘.‘;
		len--;
	}//按4个方向进行深搜
	if (len_s.size() != 0)
	return len_s.top();//最后找到最小的路径
	else return -1;
}

  


结果随机数据超时25个
技术分享
233333,老子辛辛苦苦打的代码就这样挂了。于是老老实实去找广搜了。于是查了各个博客的方法,查了下深搜广搜,终于发现了这两种方法,并找到了广搜的解决方案。http://yes2.me/archives/424
于是试着用广搜敲敲。中间的代码就不展示了,最后代码成了这个样子。
#include
#include
using namespace std;
int least_step(char (*p)[21], int n, int m);
struct path {
	path(int a, int b, int c) : x(a), y(b), floor(c) {}
	int x, y;
	int floor;//记录当前节点的层数
};
int main() {
	int n, m;
	char maze[21][21];
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> maze[i][j];
		}
	}
	cout << least_step(maze, n, m) << endl;
	return 0;
}
int least_step(char (*p)[21], int n, int m) {
	int step = 0, i = 0, j = 0, flag = 1;
	queue road;
	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (p[i][j] == ‘S‘) {
				flag = 0;//便于退出2重循环
				break;
			}
		}
		if (!flag) break;
	}
	road.push(path(i, j, 0));
	p[road.front().x][road.front().y] = ‘#‘;
	while (1) {
		if (p[road.front().x][road.front().y + 1] == ‘E‘ &&
			road.front().y + 1 < m) {
			step++;
			return step;
		}
		if (p[road.front().x + 1][road.front().y] == ‘E‘ &&
			road.front().x + 1 < n) {
			step++;
			return step;
		}
		if (p[road.front().x - 1][road.front().y] == ‘E‘ &&
			road.front().x - 1 > 0) {
			step++;
			return step;
		}
		if (p[road.front().x][road.front().y - 1] == ‘E‘ &&
			road.front().y - 1 > 0) {
			step++;
			return step;
		}//若搜索到终点,则返回步数
		if (p[road.front().x][road.front().y + 1] == ‘.‘ &&
			road.front().y + 1 < m) {
				p[road.front().x][road.front().y + 1] = ‘#‘;
				if (road.front().floor == step) {
					step++;
				}
			road.push(path(road.front().x, road.front().y + 1, step));
		}
		if (p[road.front().x + 1][road.front().y] == ‘.‘ &&
			road.front().x + 1 < n) {
			p[road.front().x + 1][road.front().y] = ‘#‘;
			if (road.front().floor == step) {
				step++;
			}
			road.push(path(road.front().x + 1, road.front().y, step));
		}
		if (p[road.front().x - 1][road.front().y] == ‘.‘ &&
			road.front().x - 1 > 0) {
			p[road.front().x - 1][road.front().y] = ‘#‘;
			if (road.front().floor == step) {
				step++;
			}
			road.push(path(road.front().x - 1, road.front().y, step));
		}
		if (p[road.front().x][road.front().y - 1] == ‘.‘ &&
			road.front().y - 1 > 0) {
			p[road.front().x][road.front().y - 1] = ‘#‘;
			if (road.front().floor == step) {
				step++;
			}
			road.push(path(road.front().x, road.front().y - 1, step));
		}//4个方向去按层寻找,之后同一层的节点不重复加,把找过的节点标志为墙,把 //合适的点压紧队列。
		road.pop();//搜过一个队头后弹出队列
		if (road.size() == 0) return -1;//发现队列中没有节点,说明每条路都走到了 //绝境,不能走下去了
	}
}
打的时候很艰辛,主要是层数的记录,我没有想到简单的方法,只是简单的用一个变量记录,然后每次每一次判断看当前节点是不是正在处理的这一层,在决定step是否加1。更傻#的是,之前的函数参数传递还搞了一下,传递2维数组用指针数组,而不是数组指针,而且要把声明部分改掉,不能只改定义部分的接口,因为这个耽误好多时间,看来C没学扎实。。。。
后来同学问我这道题,当然她自己敲了一下,我看了一下,比我的好多了(后来知道她也是在百度上找了一下)。在此借鉴一下。
#include
#include
#include
#include
using namespace std;
struct Node {
int x;
int y;
int step;
Node(int x1, int y1, int step1) : x(x1), y(y1), step(step1) {}
Node() {}
} s, e;
int main() {
int n, m, sx, sy, ex, ey;
cin >> n;
cin >> m;
int i, j;
int xx, yy;
bool flag = -1;
Node node(0, 0, 0);
char c;
queue maza;
int point[100][100];
bool visit[100][100];
int d[4][2] = {
{0, 1} , {1, 0}, {0, -1}, {-1, 0}
};
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cin >> c;
visit[i][j] = 0;
if (c == ‘S‘) {
sx = i;
sy = j;
point[i][j] = 1;
} else if (c == ‘E‘) {
ex = i;
ey = j;
point[i][j] = 1;
} else if(c == ‘!‘) {
point[i][j] = 0;
} else if (c == ‘#‘) {
point[i][j] = 0;
}
else point[i][j] = 1;
}
}
Node s(sx, sy, 0), e(ex, ey, 0);
maza.push(s);
while (!maza.empty()) {
node = maza.front();
maza.pop();
if (node.x == e.x && node.y == e.y) {
cout << node.step << endl;
flag = 0;
break;
}
visit[node.x][node.y] = 1;
for (i = 0; i < 4; i++) {
int x = node.x + d[i][0];
int y = node.y + d[i][1];
if (x >= 0 && y >= 0
&& visit[x][y] != 1 && point[x][y] != 0) {
Node next(x, y, node.step + 1);
visit[x][y] = 1;
maza.push(next);
}
}
}
if (flag != 0)
cout << -1 << endl;
}
关于那个变量作为数组大小的问题也百度了一下,是编译器扩展的问题,本来是不可以这样做的,但是devc++的编译器有编译器扩展支持了这一做法。
最后给一下TA给的答案,
#include
#include
#include
#include
using std::cin;
using std::cout;
using std::endl;
using std::queue;
int n, m;
class state {
private:
int s_x, s_y;
int e_x, e_y;
int step;
public:
state() {step = 0;}
state(int a, int b, int c, int d) {
s_x = a;
s_y = b;
e_x = c;
e_y = d;
step = 0;
}
bool ismeet();
bool isvaild();
friend void judge();
};
bool state::ismeet() {
if (s_x == e_x && s_y == e_y)
return true;
else
return false;
}
bool state::isvaild() {
if (s_x > 0 && s_x <= n && s_y > 0 && s_y <= m)
return true;
else
return false;
}
int s_x, s_y, e_x, e_y;
int mov[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
char aa[21][21];
bool isvisit[21][21];
void judge();
int main() {
cin >> n >> m;
memset(isvisit, false, sizeof(isvisit));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> aa[i][j];
if (aa[i][j] == ‘S‘) {
s_x = i;
s_y = j;
aa[i][j] = ‘.‘;
}
if (aa[i][j] == ‘E‘) {
e_x = i;
e_y = j;
aa[i][j] = ‘.‘;
}
}
}
judge();
return 0;
}
void judge() {
queue vv;
vv.push(state(s_x, s_y, e_x, e_y));
state temp, hold;
while (!vv.empty()) {
temp = vv.front();
vv.pop();
for (inti = 0; i < 4; i++) {
hold.s_x = temp.s_x + mov[i][0];
hold.s_y = temp.s_y + mov[i][1];
hold.step = temp.step + 1;
hold.e_x = temp.e_x;
hold.e_y = temp.e_y;
if (hold.isvaild() && aa[hold.s_x][hold.s_y] == ‘.‘) {
if (!isvisit[hold.s_x][hold.s_y]) {
isvisit[hold.s_x][hold.s_y] = true;
if (hold.ismeet()) {
cout << hold.step << endl;
return;
} else {
vv.push(hold);
}
}
}
}
}
cout <<‘-1‘ <<endl;
}
 

  


































以上是关于一道很难的数学题!的主要内容,如果未能解决你的问题,请参考以下文章

一道数学难题

有一道奇怪的数学题。(下边是详细内容)

C++一道题 跪求解答

[HNOI2011]数学作业

[HNOI2011]数学作业

洛谷P3216 [HNOI2011]数学作业