답안 #28658

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
28658 2017-07-16T08:28:07 Z 점수판에 아이디와 팀명이 같이 표기되니, 신중하게 적어주세요.(#1186, kajebiii, secsegy, woqja125) Test Data Creation (FXCUP2_testdata) C++14
0 / 1
4000 ms 13680 KB
#include <stdio.h>
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define SZ(v) ((int)(v).size())
#define ALL(v) (v).begin(),(v).end()
#define one first
#define two second
typedef long long ll;
typedef pair<int, int> pi; typedef pair<ll, int> pli; typedef pair<ll, pi> plp;
typedef tuple<int, int, int> ti; typedef tuple<ll, int, int> tli;
const int INF = 0x3f2f1f0f;
const ll LINF = 1ll * INF * INF;

const int MAX_N = 3e2 + 10;

struct pair_hash {
	template <class T1, class T2>
	std::size_t operator () (const std::pair<T1, T2> &p) const {
		auto h1 = std::hash<T1>{}(p.first);
		auto h2 = std::hash<T2>{}(p.second);

		// Mainly for demonstration purposes, i.e. works but is overly simple
		// In the real world, use sth. like boost.hash_combine
		return h1 ^ h2;
	}
};


int N, M, Nr[MAX_N * MAX_N];
unordered_map<pi, int, pair_hash> dis;
unordered_set<pi, pair_hash> inQ;
pi toPi(int s, int t) {
	if(t == 0) return pi(s/M, s%M);
	return pi(s/N, s%N);
}
int toS(int x, int y, int t) {
	if(t == 0) return x*M + y;
	return x*N + y;
}
bool isIn(int x, int y, int t) {
	if(t == 0) return !(x<0 || y<0 || x>=N || y>=M);
	return !(x<0 || y<0 || x>=M || y>=N);
}
queue<pi> Q;
void push(int x, int y, int c) {
//	printf("push %d %d | %d\n", x, y, c);
	if(dis[pi(x,y)] == 0 || dis[pi(x,y)] > c) {
		dis[pi(x,y)] = c;
		if(inQ.find(pi(x, y)) == inQ.end()) {
			inQ.insert(pi(x, y));
			Q.push(pi(x, y));
		}
	}
}
void findAns(int a, int b) {
	if(a == 0 && b == 0) {
		Nr[0] = -1;
		return;
	}
	int ax, ay; tie(ax, ay) = toPi(a, 0);
	int bx, by; tie(bx, by) = toPi(b, 1);
	vector<int> ls[2];
	for(int k=0; k<4; k++) {
		int nx = ax + "1012"[k] - '1', ny = ay + "0121"[k] - '1';
		if(!isIn(nx, ny, 0)) continue;
		int na = toS(nx, ny, 0);
		ls[0].push_back(na);
		if(dis[pi(na, b)] + Nr[a] == dis[pi(a, b)]) {
			Nr[a] = -1;
			return findAns(na, b);
		}
	}
	for(int k=0; k<4; k++) {
		int nx = bx + "1012"[k] - '1', ny = by + "0121"[k] - '1';
		if(!isIn(nx, ny, 1)) continue;
		int nb = toS(nx, ny, 1);
		ls[1].push_back(nb);
		if(dis[pi(a, nb)] + Nr[b] == dis[pi(a, b)]) {
			Nr[b] = -1;
			return findAns(a, nb);
		}
	}
	if(a == b) {
		for(int na : ls[0]) for(int nb : ls[1]) {
			if(dis[pi(na, nb)] + Nr[a] == dis[pi(a, b)]) {
				Nr[a] = -1;
				return findAns(na, nb);
			}
		}
	}
	assert(false);
}
int main() {
	cin >> M >> N;
	for(int i=0; i<N*M; i++) scanf("%d", &Nr[i]);
	Q.push(pi(0, 0)); dis[pi(0, 0)] = Nr[0]; inQ.insert(pi(0, 0));
	while(!Q.empty()) {
		inQ.erase(inQ.find(Q.front()));
		int a, b; tie(a, b) = Q.front(); Q.pop();
//		if(a == b) printf("%d %d [%d]\n", a, b, dis[pi(a, b)]);
		if(a+1 == N*M && b+1 == N*M) {
			printf("%d\n", dis[pi(a, b)]);
			break;
		}
		int ax, ay; tie(ax, ay) = toPi(a, 0);
		int bx, by; tie(bx, by) = toPi(b, 1);
		vector<int> ls[2];
		for(int k=0; k<4; k++) {
			int nx = ax + "1012"[k] - '1', ny = ay + "0121"[k] - '1';
			if(!isIn(nx, ny, 0)) continue;
			int na = toS(nx, ny, 0);
			ls[0].push_back(na);
			push(na, b, dis[pi(a,b)] + Nr[na]);
		}
		for(int k=0; k<4; k++) {
			int nx = bx + "1012"[k] - '1', ny = by + "0121"[k] - '1';
			if(!isIn(nx, ny, 1)) continue;
			int nb = toS(nx, ny, 1);
			ls[1].push_back(nb);
			push(a, nb, dis[pi(a, b)] + Nr[nb]);
		}
		for(int k=0; k<2; k++) {
			sort(ALL(ls[k]));
		}
		for(int i=0, j=0; i<SZ(ls[0]) && j<SZ(ls[1]); ) {
			if(ls[0][i] == ls[1][j]) {
				int v = ls[0][i];
//				printf("when %d %d -> %d %d\n", a, b, v, v);
				push(v, v, dis[pi(a, b)] + Nr[v]);
				i++;
			}else if(ls[0][i] < ls[1][j]) i++; else j++;
		}
	}
	findAns(N*M-1, N*M-1);
	for(int i=0; i<N; i++, puts("")) for(int j=0; j<M; j++) {
		printf("%d ", Nr[i*M+j] == -1 ? 1 : 0);
	}
	return 0;
}

Compilation message

testdata.cpp: In function 'int main()':
testdata.cpp:99:46: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i=0; i<N*M; i++) scanf("%d", &Nr[i]);
                                              ^
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 2408 KB Correct
2 Correct 0 ms 2408 KB Correct
3 Correct 1343 ms 5604 KB Correct
4 Execution timed out 4000 ms 13680 KB Execution timed out
5 Halted 0 ms 0 KB -