結果

問題 No.340 雪の足跡
ユーザー asugen0402asugen0402
提出日時 2019-04-15 11:37:16
言語 C
(gcc 12.3.0)
結果
AC  
実行時間 243 ms / 1,000 ms
コード長 6,436 bytes
コンパイル時間 367 ms
コンパイル使用メモリ 33,664 KB
実行使用メモリ 116,664 KB
最終ジャッジ日時 2024-09-22 07:49:43
合計ジャッジ時間 5,116 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 31 ms
116,536 KB
testcase_01 AC 32 ms
116,536 KB
testcase_02 AC 30 ms
116,536 KB
testcase_03 AC 31 ms
116,664 KB
testcase_04 AC 31 ms
116,532 KB
testcase_05 AC 31 ms
116,540 KB
testcase_06 AC 31 ms
116,536 KB
testcase_07 AC 31 ms
116,536 KB
testcase_08 AC 30 ms
116,540 KB
testcase_09 AC 31 ms
116,408 KB
testcase_10 AC 31 ms
116,412 KB
testcase_11 AC 31 ms
116,408 KB
testcase_12 AC 31 ms
116,412 KB
testcase_13 AC 31 ms
116,536 KB
testcase_14 AC 39 ms
116,664 KB
testcase_15 AC 41 ms
116,532 KB
testcase_16 AC 38 ms
116,404 KB
testcase_17 AC 45 ms
116,536 KB
testcase_18 AC 42 ms
116,536 KB
testcase_19 AC 45 ms
116,532 KB
testcase_20 AC 150 ms
116,540 KB
testcase_21 AC 124 ms
116,536 KB
testcase_22 AC 33 ms
116,536 KB
testcase_23 AC 177 ms
116,404 KB
testcase_24 AC 145 ms
116,532 KB
testcase_25 AC 151 ms
116,536 KB
testcase_26 AC 53 ms
116,536 KB
testcase_27 AC 36 ms
116,664 KB
testcase_28 AC 49 ms
116,536 KB
testcase_29 AC 195 ms
116,536 KB
testcase_30 AC 137 ms
116,536 KB
testcase_31 AC 209 ms
116,532 KB
testcase_32 AC 239 ms
116,408 KB
testcase_33 AC 206 ms
116,660 KB
testcase_34 AC 243 ms
116,532 KB
testcase_35 AC 165 ms
116,532 KB
testcase_36 AC 166 ms
116,408 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_ON			1										// 汎用フラグ - ON
#define D_OFF			0										// 汎用フラグ - OFF
#define D_SIZE_MAX		3005									// 最大サイズ
#define D_WAY_CNT		4										// 方向数
#define D_WAY_R			0										// 方向 - 右
#define D_WAY_L			1										// 方向 - 左
#define D_WAY_D			2										// 方向 - 下
#define D_WAY_U			3										// 方向 - 上
#define D_STACK_MAX		D_SIZE_MAX								// 最大スタック数

// 内部構造体 - 位置情報
typedef struct Pos {
	char mc1Con[D_WAY_CNT];										// 接続
	char mcDone;												// 処理済フラグ
} Pos;

// 内部構造体 - スタック情報
typedef struct Stack {
	int miX, miY;												// 位置
} Stack;

// 内部変数
static FILE *szpFpI;											// 入力
static int si2Mx[D_SIZE_MAX][D_SIZE_MAX];						// 横移動[位置Y][位置X]
static int si2My[D_SIZE_MAX][D_SIZE_MAX];						// 縦移動[位置X][位置Y]
static int siW, siH;											// 幅・高さ
static Pos sz2Pos[D_SIZE_MAX][D_SIZE_MAX];						// 位置情報[位置X][位置Y]
static Stack sz1Stack[D_STACK_MAX];								// スタック
static int siSCnt;												// スタック数
static int siSSNo;												// スタック位置 - セット
static int siSGNo;												// スタック位置 - 取得

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpA;
#endif

// スタック - 追加
int
fStackAdd(
	int piX						// <I> 位置X
	, int piY					// <I> 位置Y
)
{
	// 処理済フラグ
	if (sz2Pos[piX][piY].mcDone != D_OFF) {
		return 0;
	}
	sz2Pos[piX][piY].mcDone = D_ON;

	// セット
	sz1Stack[siSSNo].miX = piX;
	sz1Stack[siSSNo].miY = piY;

	// スタック数
	siSCnt++;

	// スタック位置 - セット
	if (siSSNo < D_STACK_MAX - 1) {
		siSSNo++;
	}
	else {
		siSSNo = 0;
	}

	return 0;
}

// スタック - 取得
int
fStackGet(
	Stack *pzpRet				// <O> 取得値
)
{
	// スタック数
	if (siSCnt < 1) {
		return -1;
	}
	siSCnt--;

	// 取得
	memcpy(pzpRet, &sz1Stack[siSGNo], sizeof(Stack));

	// スタック位置 - 取得
	if (siSGNo < D_STACK_MAX - 1) {
		siSGNo++;
	}
	else {
		siSGNo = 0;
	}

	return 0;
}

// 最短距離 - 取得
int
fGetMin(
)
{
	int i, j, k;

	// 移動なし
	if (siW == 1) {
		if (siH == 1) {
			return 0;
		}
	}

	// スタック - 初期位置
	fStackAdd(0, 0);

	// 最短距離 - セット
	int liLen = -1;
	for (i = 1; ; i++) {

		// スタック有無
		int liSCnt = siSCnt;
		if (liSCnt < 1) {
			break;
		}

		// スタック数でループ
		for (j = 0; j < liSCnt; j++) {
			Stack lzStack;
			fStackGet(&lzStack);

			// 各方向へ移動
			Pos *lzpPos = &sz2Pos[lzStack.miX][lzStack.miY];
			for (k = 0; k < D_WAY_CNT; k++) {
				if (lzpPos->mc1Con[k] != D_ON) {
					continue;
				}

				// 移動先
				int liX = lzStack.miX;
				int liY = lzStack.miY;
				switch (k) {
					case D_WAY_R:	liX++;		break;
					case D_WAY_L:	liX--;		break;
					case D_WAY_D:	liY++;		break;
					case D_WAY_U:	liY--;		break;
				}

				// 到着
				if (liX == siW - 1) {
					if (liY == siH - 1) {
						return i;
					}
				}

				// スタック - 追加
				fStackAdd(liX, liY);
			}
		}
	}

	return -1;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1~
)
{
	int i, j;
	char lc1Buf[1024], lc1Out[1024];

	// データ - 初期化
	memset(si2Mx, 0, sizeof(si2Mx));							// 横移動
	memset(si2My, 0, sizeof(si2My));							// 縦移動
	memset(sz2Pos, 0, sizeof(sz2Pos));							// 位置情報
	siSCnt = 0;													// スタック数
	siSSNo = 0;													// スタック位置 - セット
	siSGNo = 0;													// スタック位置 - 取得

	// 入力 - セット
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpI = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#else
	szpFpI = stdin;
#endif

	// 幅・高さ・人数 - 取得
	int liHCnt;
	fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
	sscanf(lc1Buf, "%d%d%d", &siW, &siH, &liHCnt);

	// 人数でループ
	for (i = 0; i < liHCnt; i++) {

		// 経路数 - 取得
		int liRCnt;
		fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
		sscanf(lc1Buf, "%d", &liRCnt);

		// 初期位置
		int liFrom;
		fscanf(szpFpI, "%d", &liFrom);

		// 経路 - 取得
		for (j = 0; j < liRCnt; j++) {
			int liTo;
			fscanf(szpFpI, "%d", &liTo);

			// 大小
			int liFNo, liTNo;
			if (liFrom < liTo) {
				liFNo = liFrom;
				liTNo = liTo;
			}
			else {
				liFNo = liTo;
				liTNo = liFrom;
			}

			// 商・剰余
			int liDF = liFNo / siW;
			int liDT = liTNo / siW;
			int liMF = liFNo % siW;
			int liMT = liTNo % siW;

			// 移動 - セット
			if (liDF == liDT) {									// 横移動
				si2Mx[liDF][liMF]++;
				si2Mx[liDF][liMT]--;
			}
			else {												// 縦移動
				si2My[liMF][liDF]++;
				si2My[liMF][liDT]--;
			}

			// 位置移動
			liFrom = liTo;
		}
		fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
	}

	// 位置情報 - 接続位置 - セット
	for (i = 0; i < siH; i++) {
		int liSum = 0;
		for (j = 0; j < siW - 1; j++) {
			liSum += si2Mx[i][j];
			if (liSum > 0) {
				sz2Pos[j][i].mc1Con[D_WAY_R] = D_ON;
				sz2Pos[j + 1][i].mc1Con[D_WAY_L] = D_ON;
			}
		}
	}
	for (i = 0; i < siW; i++) {
		int liSum = 0;
		for (j = 0; j < siH - 1; j++) {
			liSum += si2My[i][j];
			if (liSum > 0) {
				sz2Pos[i][j].mc1Con[D_WAY_D] = D_ON;
				sz2Pos[i][j + 1].mc1Con[D_WAY_U] = D_ON;
			}
		}
	}

	// 最短距離 - 取得
	int liMin = fGetMin();

	// 結果 - セット
	if (liMin < 0) {
		sprintf(lc1Out, "Odekakedekinai..\n");
	}
	else {
		sprintf(lc1Out, "%d\n", liMin);
	}

	// 結果 - 表示
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// 残データ有無
#ifdef D_TEST
	lc1Buf[0] = '\0';
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, "")) {
		siRes = -1;
	}
#endif

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpI);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}

0