键盘(如何找到最短路径) [英] Keyboarding (how to find shortest path)

查看:115
本文介绍了键盘(如何找到最短路径)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处解释的问题 Keyboarding& ndash; Kattis,ICPC世界总决赛 [ ^ ]



我尝试了什么:



我先做的是放置所有字符在二维数组中,找到所有字母在数组中的位置,并添加索引差异的绝对值以获得最短路径,这仅适用于第一个示例,如果有多个,我将需要做什么彼此相邻的一封信。我做了什么不会得到最短的路径。我读到了Dijkstra的算法,你怎么能在这个问题中使用?

problem explained here Keyboarding – Kattis, ICPC World Finals[^]

What I have tried:

What I did first was to put all characters in a 2-D array, find where all the letters are in array and adding the absolute value of the difference of the indexes to get shortest path, this only worked for the first example, what would i have to do if there is more than one of the same letter next to each other. what i did won't get the shortest path. I read about Dijkstra's algorithm, how can you use in this problem?

推荐答案

引用:

我读到了Dijkstra的算法,你怎么能在这个问题上使用?

I read about Dijkstra's algorithm, how can you use in this problem?

你没有,它不适用于这种问题。

在像这样的竞赛中,它从来不是一个经典的问题,众所周知的解决方案也不适用。

在示例1中,两个键之间的距离为出租车几何 - 维基百科,免费百科全书 [ ^ ]。

但是当按键重复时,它没有,你必须设计自己的算法



Dijkstra的算法 - 维基百科,免费的百科全书 [ ^ ]



你必须小心给出的例子:

You don't, it is not for this kind of problem.
In contests like this one, it is never a classical problem, and well known solutions do not apply.
In example 1, the distance between 2 keys mach Taxicab geometry - Wikipedia, the free encyclopedia[^].
But when keys are repeating, it don't, you have to devise your own algorithm.

Dijkstra's algorithm - Wikipedia, the free encyclopedia[^]

And you have to be careful with examples given:

6 4
AXYB
BBBB
KLMB
OPQB
DEFB
GHI*
AB



是最好的解决方案7与:


is claimed with best solution 7 with:

Select Left Left Left Select Down Select



但如果你这样做:


But if you do:

Select Down Select Left Down Select






or

Select Down Left Select Down Select



它是6




[更新]

我刚完成了我的程序

示例2甚至最差,我得到146而不是160。

我终于得到了它,我跳过了/>
如果没有这样的单位正方形,则光标不会移动。

使某些键无法访问。

My坏了。



[更新]

这是我的代码,但我担心你会有问题使用它,它是Clipper语言。


it is 6


[Update]
I just finished my program
Example 2 is even worst, I get 146 instead of 160.
I finally got it, I skipped
If there is no such unit square, the cursor does not move.
which make some keys unreachable.
My bad.

[Update]
Here is my code, but I fear you will have problems to use it, it is in Clipper Language.

*	https://online.acmicpc.org/problems/keyboard
procedure kb()
	cls
	*	chargement des données
	KB_init({"ABCDEFG", "HIJKLMN", "OPQRSTU", "VWXYZ**"}, "CONTEST")
	KB_init({"12233445566778899000", "QQWWEERRTTYYUUIIOOPP", "-AASSDDFFGGHHJJKKLL*", "--ZZXXCCVVBBNNMM--**", "--------------------"}, "ACM-ICPC-WORLD-FINALS-2015")
	KB_init({"ABCDEFGHIJKLMNOPQZY", "X*****************Y"}, "AZAZ")
	KB_init({"AXYB", "BBBB", "KLMB", "OPQB", "DEFB", "GHI*"}, "AB")
	return

procedure KB_init(clav, chn)
	kb_max= (50+50)*10000
	ltr= array(len(clav), len(clav[1]))
	mat= array(len(clav), len(clav[1]))
	cnt= array(len(clav), len(clav[1]))
	for row=1 to len(clav)
		afill(mat[row], .f.)
		afill(cnt[row], kb_max)
		for col=1 to len(clav[1])
			ltr[row,col]= substr(clav[row],col,1)
		next
		? clav[row]
	next
	mat[1,1l]= .T.
	cnt[1, 1]= 0

	?
	? chn

	KB_propag(ltr, mat, cnt)
	for scan=1 to len(chn)
		touche= chn[scan]
		KB_set(ltr, mat, cnt, touche)
		KB_propag(ltr, mat, cnt)
		* ? touche
		best= kb_max
		for row=1 to len(mat)
			for col=1 to len(mat[row])
				if ltr[row, col]= touche
					best= min(best, cnt[row, col])
					*?? cnt[row, col]
				endif
			next
		next
		* ?? best
		* inkey(0)
	next

	* ? "*"
	best= kb_max
	for row=1 to len(mat)
		for col=1 to len(mat[row])
			if ltr[row, col]= "*"
				best= min(best, cnt[row, col])
				* ?? cnt[row, col]
			endif
		next
	next
	* ?? best
	? best+ len(chn)+ 1
	?
	?
	inkey(0)
	return

procedure KB_set(ltr, mat, cnt, touche)
	for row=1 to len(mat)
		for col=1 to len(mat[row])
			if ltr[row, col]= touche
				mat[row, col]= .T.
			else
				mat[row, col]= .F.
				cnt[row, col]= kb_max
			endif
		next
	next
	return

procedure KB_propag(ltr, mat, cnt)
	*	calculer la prochaine etape
	boucle= .T.
	do while boucle
		boucle= .F.
		for row=1 to len(mat)
			for col=1 to len(mat[row])
				if mat[row, col]
					*	est
					if col < len(mat[row])
						offset=1
						do while col+ offset < len(mat[row]) .and. ltr[row, col]= ltr[row, col+ offset]
							offset++
						enddo
						if ltr[row, col] != ltr[row, col+ offset]
							if cnt[row, col+ offset] > cnt[row, col]+1
								cnt[row, col+ offset] = cnt[row, col]+1
								mat[row, col+ offset] = .T.
								boucle= .T.
							endif
						endif
					endif
					*	ouest
					if col > 1
						offset= -1
						do while col+ offset > 1 .and. ltr[row, col]= ltr[row, col+ offset]
							offset--
						enddo
						if ltr[row, col] != ltr[row, col+ offset]
							if cnt[row, col+ offset] > cnt[row, col]+1
								cnt[row, col+ offset] = cnt[row, col]+1
								mat[row, col+ offset] = .T.
								boucle= .T.
							endif
						endif
					endif
					*	sud
					if row < len(mat)
						offset=1
						do while row+ offset < len(mat) .and. ltr[row, col]= ltr[row+ offset, col]
							offset++
						enddo
						if ltr[row, col] != ltr[row+ offset, col]
							if cnt[row+ offset, col] > cnt[row, col]+1
								cnt[row+ offset, col] = cnt[row, col]+1
								mat[row+ offset, col] = .T.
								boucle= .T.
							endif
						endif
					endif
					*	nord
					if row > 1
						offset= -1
						do while row+ offset > 1 .and. ltr[row, col]= ltr[row+ offset, col]
							offset--
						enddo
						if ltr[row, col] != ltr[row+ offset, col]
							if cnt[row+ offset, col] > cnt[row, col]+1
								cnt[row+ offset, col] = cnt[row, col]+1
								mat[row+ offset, col] = .T.
								boucle= .T.
							endif
						endif
					endif
					mat[row, col]= .F.
				endif
			next
		next
		*
		if boucle
			boucle= .F.
			for row= len(mat) to 1 step -1
				for col= len(mat[row]) to 1 step -1
					if mat[row, col]
						*	est
						if col < len(mat[row])
							offset=1
							do while col+ offset < len(mat[row]) .and. ltr[row, col]= ltr[row, col+ offset]
								offset++
							enddo
							if ltr[row, col] != ltr[row, col+ offset]
								if cnt[row, col+ offset] > cnt[row, col]+1
									cnt[row, col+ offset] = cnt[row, col]+1
									mat[row, col+ offset] = .T.
									boucle= .T.
								endif
							endif
						endif
						*	ouest
						if col > 1
							offset= -1
							do while col+ offset > 1 .and. ltr[row, col]= ltr[row, col+ offset]
								offset--
							enddo
							if ltr[row, col] != ltr[row, col+ offset]
								if cnt[row, col+ offset] > cnt[row, col]+1
									cnt[row, col+ offset] = cnt[row, col]+1
									mat[row, col+ offset] = .T.
									boucle= .T.
								endif
							endif
						endif
						*	sud
						if row < len(mat)
							offset=1
							do while row+ offset < len(mat) .and. ltr[row, col]= ltr[row+ offset, col]
								offset++
							enddo
							if ltr[row, col] != ltr[row+ offset, col]
								if cnt[row+ offset, col] > cnt[row, col]+1
									cnt[row+ offset, col] = cnt[row, col]+1
									mat[row+ offset, col] = .T.
									boucle= .T.
								endif
							endif
						endif
						*	nord
						if row > 1
							offset= -1
							do while row+ offset > 1 .and. ltr[row, col]= ltr[row+ offset, col]
								offset--
							enddo
							if ltr[row, col] != ltr[row+ offset, col]
								if cnt[row+ offset, col] > cnt[row, col]+1
									cnt[row+ offset, col] = cnt[row, col]+1
									mat[row+ offset, col] = .T.
									boucle= .T.
								endif
							endif
						endif
						mat[row, col]= .F.
					endif
				next
			next
		endif
	enddo
	return


我发现这个解决方案,但它在c ++,我知道c#,我不明白,有人可以解释



I found this solution but its in c++ and I know c#, I dont understand it, can someone please explain

using namespace std;

int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, -1, 0, 1 };
int mv[50][50][4];
int best[50][50];

int _tmain(int argc, _TCHAR* argv[])
{
    int Y, X;
    while (cin >> Y >> X) {
        vector<string> g(Y);
        for (int i = 0; i < Y; i++) cin >> g[i];
        string message;
        cin >> message;
        message += '*';

        memset(mv, -1, sizeof(mv));
        for (int y = 0; y < Y; y++)
        for (int x = 0; x < X; x++)
        for (int d = 0; d < 4; d++) {
            int x2 = x, y2 = y;
            for (int n = 0;; n++) {
                if (x2 < 0 || x2 >= X || y2 < 0 || y2 >= Y) break;
                if (g[y2][x2] != g[y][x]) {
                    mv[y][x][d] = n;
                    break;
                }
                x2 += dx[d]; y2 += dy[d];
            }
        }

        vector<pair<int, pair<short, short> > > cur;
        cur.push_back(make_pair(0, make_pair(0, 0)));

        for (int i = 0; i < message.size(); i++) {
            memset(best, 63, sizeof(best));
            vector<pair<short, short> > v;
            int dist = 0, curi = 0;
            sort(cur.begin(), cur.end());
            for (;;) {
                if (v.empty()) {
                    if (curi == cur.size()) break;
                    dist = cur[curi].first;
                }
                while (curi < cur.size() && cur[curi].first == dist) {
                    v.push_back(cur[curi++].second);
                }
                vector<pair<short, short> > v2;
                for (int j = 0; j < v.size(); j++) {
                    int x = v[j].first, y = v[j].second;
                    if (best[y][x] <= dist) continue;
                    best[y][x] = dist;
                    for (int d = 0; d < 4; d++) if (mv[y][x][d] != -1) {
                        int x2 = x + dx[d] * mv[y][x][d], y2 = y + dy[d] * mv[y][x][d];
                        if (best[y2][x2] > dist + 1) {
                            v2.push_back(make_pair(x2, y2));
                        }
                    }
                }
                v.swap(v2);
                dist++;
            }

            cur.clear();
            for (int y = 0; y < Y; y++)
            for (int x = 0; x < X; x++) if (g[y][x] == message[i]) {
                cur.push_back(make_pair(best[y][x] + 1, make_pair(x, y)));
            }
        }

        int ret = 1000000000;
        for (int i = 0; i < cur.size(); i++) ret = min(ret, cur[i].first);
        cout << ret << endl;
    }


这篇关于键盘(如何找到最短路径)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆