Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Andrés Mejía
committed
Oct 27, 2011
1 parent
bbe55d6
commit df668a3
Showing
151 changed files
with
1,037,133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
1 | ||
2 2 | ||
##### | ||
# 1 # | ||
#2#3# | ||
# 4 # | ||
##### |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Sample solution of NWERC-2004-Pipes by Ola Hugosson | ||
#include <stdio.h> | ||
#include <assert.h> | ||
#include <iostream> | ||
using namespace std; | ||
|
||
#define D(x) cout << #x " = " << (x) << endl | ||
|
||
#define NONE 0 | ||
#define IN 1 | ||
#define OUT 2 | ||
#define FEDECOST 0xfede | ||
#define MAXSTATES 5798 // pre-calculated | ||
#define GETTYPE(sidx,i) (((sidx)>>(2*(i)))&3) | ||
#define SETTYPE(type,i) (((type)<<(2*(i)))) | ||
|
||
int state[MAXSTATES], newstate[MAXSTATES], map[MAXSTATES]; | ||
short invmap[1<<(2*11)]; | ||
|
||
// calculate a map used to enumerate all valid boundaries | ||
int genmap(int c, int n, int i, int nest, int sidx) | ||
{ | ||
printf("c = %d, n = %d, i = %d, nest = %d, sidx = %x\n", c, n, i, nest, sidx); | ||
if (nest>=0 && i<=c) { | ||
n=genmap(c,n,i+1,nest, sidx|SETTYPE(NONE,i)); | ||
n=genmap(c,n,i+1,nest+1,sidx|SETTYPE(IN,i)); | ||
n=genmap(c,n,i+1,nest-1,sidx|SETTYPE(OUT,i)); | ||
} | ||
else if (nest==0){ | ||
map[n++]=sidx; | ||
printf("mask = %X, nest = 0\n", sidx); | ||
} | ||
assert(n<=MAXSTATES); | ||
return n; | ||
} | ||
|
||
int main(){ | ||
int floors, r, c, x, y, n, i, j, sidx, left, up, right, down, cost, prevcost; | ||
char lrwall[30],udwall[30]; | ||
for( scanf("%d",&floors); floors--;) { | ||
scanf("%d %d\n",&r,&c); | ||
gets(udwall); //dummy-input | ||
n=genmap(c,0,0,0,0); | ||
|
||
for (int i = 0; i < n; ++i){ | ||
int mask = map[i]; | ||
printf("mask = %X\n", mask); | ||
for (int j = 0; j <= c; ++j){ | ||
int what = GETTYPE(mask, j); | ||
switch (what){ | ||
case NONE: | ||
cout << "NONE "; | ||
break; | ||
case IN: | ||
cout << "IN "; | ||
break; | ||
case OUT: | ||
cout << "OUT "; | ||
break; | ||
} | ||
} | ||
cout << endl; | ||
} | ||
|
||
for(i=0; i<n; i++) { | ||
invmap[map[i]]=i; | ||
newstate[i]=FEDECOST; | ||
} | ||
newstate[invmap[0]]=0; | ||
for(y=0; y<r; y++) { | ||
gets(lrwall); | ||
gets(udwall); | ||
for(x=0; x<c; x++) { | ||
for(i=0; i<n; i++) { | ||
state[i]=newstate[i]; | ||
newstate[i]=FEDECOST; | ||
} | ||
for(i=0; i<n; i++) { | ||
static const char lut[3][3][3] = | ||
{{{1, IN, OUT }, {2, NONE, IN }, {2, NONE, OUT }}, | ||
{{2, NONE, IN }, {1, NONE, NONE}, {0, NONE, NONE}}, // the 0 prevents internal loops | ||
{{2, NONE, OUT }, {1, NONE, NONE}, {1, NONE, NONE}}}; | ||
prevcost = (x>0 ? state[i] : ((map[i]&3)==NONE) ? state[invmap[map[i]>>2]] : FEDECOST); | ||
if (prevcost>=FEDECOST) | ||
continue; // speed up somewhat | ||
sidx=map[i]; | ||
left=GETTYPE(sidx,x); | ||
up =GETTYPE(sidx,x+1); | ||
for(j=0; j<lut[left][up][0]; j++) { | ||
down =lut[left][up][1+j]; | ||
right=lut[left][up][2-j]; | ||
cost = prevcost + (right==NONE ? 0 : lrwall[2*x+2]-'0') + | ||
(down ==NONE ? 0 : udwall[2*x+1]-'0'); | ||
if (left==up && left!=NONE) { // find matching IN/OUT pair | ||
int nest=0, xx=(left==OUT)? x : x+1; | ||
while(nest += GETTYPE(sidx,xx)==OUT ? -1 : GETTYPE(sidx,xx)==IN ? +1 : 0) | ||
xx += nest<0 ? -1 : 1; | ||
sidx ^= SETTYPE(3,xx); // toggle IN<->OUT | ||
} | ||
sidx = sidx & ~SETTYPE(15,x) | SETTYPE(down,x) | SETTYPE(right,x+1); | ||
if (cost<newstate[invmap[sidx]]) | ||
newstate[invmap[sidx]]=cost; | ||
} | ||
} | ||
} | ||
} | ||
printf("%d\n",state[invmap[(IN<<(2*c-2))|(OUT<<(2*c))]]); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// Andrés Mejía | ||
using namespace std; | ||
#include <algorithm> | ||
#include <iostream> | ||
#include <iterator> | ||
#include <numeric> | ||
#include <sstream> | ||
#include <fstream> | ||
#include <cassert> | ||
#include <climits> | ||
#include <cstdlib> | ||
#include <cstring> | ||
#include <string> | ||
#include <cstdio> | ||
#include <vector> | ||
#include <cmath> | ||
#include <queue> | ||
#include <deque> | ||
#include <stack> | ||
#include <list> | ||
#include <map> | ||
#include <set> | ||
|
||
#define foreach(x, v) for (typeof (v).begin() x=(v).begin(); x !=(v).end(); ++x) | ||
#define For(i, a, b) for (int i=(a); i<(b); ++i) | ||
#define D(x) cout << #x " is " << x << endl | ||
|
||
const double EPS = 1e-9; | ||
int cmp(double x, double y = 0, double tol = EPS) { | ||
return (x <= y + tol) ? (x + tol < y) ? -1 : 0 : 1; | ||
} | ||
|
||
const int MAXN = 105, MAXL = 55, oo = 1 << 28; | ||
string words[MAXN]; | ||
int dist[MAXN][MAXL]; | ||
int n; | ||
|
||
long long pack(int index, int behind, int weight) { | ||
return ((long long)weight << 16L) + (behind << 8L) + index; | ||
} | ||
|
||
void unpack(long long state, int &index, int &behind, int &weight) { | ||
index = state & 255L; | ||
state >>= 8L; | ||
behind = state & 255L; | ||
state >>= 8L; | ||
weight = state; | ||
} | ||
|
||
inline bool isPrefix(const string &a, const string &b) { | ||
if (a.size() > b.size()) return false; | ||
for (int i = 0; i < a.size(); ++i) { | ||
if (a[i] != b[i]) return false; | ||
} | ||
return true; | ||
} | ||
|
||
|
||
int search() { | ||
for (int i = 0; i < n; ++i) { | ||
for (int d = 0; d < MAXL; ++d) { | ||
dist[i][d] = oo; | ||
} | ||
} | ||
|
||
priority_queue<long long, vector<long long>, greater<long long> > q; | ||
for (int i = 0; i < n; ++i) { | ||
for (int j = 0; j < n; ++j) { | ||
if (i == j) continue; | ||
if (isPrefix(words[j], words[i])) { | ||
assert(words[j].size() < words[i].size()); | ||
int diff = words[i].size() - words[j].size(); | ||
dist[i][diff] = words[i].size(); | ||
long long state = pack(i, diff, dist[i][diff]); | ||
q.push(state); | ||
} | ||
} | ||
} | ||
|
||
while (q.size() > 0) { | ||
long long state = q.top(); q.pop(); | ||
int index, behind, weight; | ||
unpack(state, index, behind, weight); | ||
//printf("Popped state <i=%d, d=%d> (%s, %s) with weight w=%d\n", index, behind, words[index].c_str(), words[index].substr(0, words[index].size() - behind).c_str(), weight); | ||
if (behind == 0) { | ||
return weight; | ||
} | ||
if (weight > dist[index][behind]) continue; | ||
|
||
const string tail = words[index].substr(words[index].size() - behind); | ||
//printf(" Tail is %s\n", tail.c_str()); | ||
assert(tail.size() == behind); | ||
|
||
for (int k = 0; k < n; ++k) { | ||
//printf(" Trying words[k=%d] = %s\n", k, words[k].c_str()); | ||
if (words[k].size() - behind >= 0 and isPrefix(tail, words[k]) ) { | ||
int new_index = k; | ||
int new_behind = words[new_index].size() - behind; | ||
int new_weight = weight + new_behind; | ||
//printf(" Option 1: Can reach state <i=%d, d=%d> (%s, %s) with weight = w=%d\n", new_index, new_behind, words[new_index].c_str(), words[new_index].substr(0, words[new_index].size() - new_behind).c_str(), new_weight ); | ||
if (new_weight < dist[new_index][new_behind]) { | ||
dist[new_index][new_behind] = new_weight; | ||
q.push( pack(new_index, new_behind, new_weight) ); | ||
//printf(" That's better.\n"); | ||
} | ||
} | ||
|
||
if (behind - words[k].size() >= 0 and isPrefix(words[k], tail) ) { | ||
int new_index = index; | ||
int new_behind = behind - words[k].size(); | ||
int new_weight = weight + 0; | ||
//printf(" Option 2: Can reach state <i=%d, d=%d> (%s, %s) with weight = w=%d\n", new_index, new_behind, words[new_index].c_str(), words[new_index].substr(0, words[new_index].size() - new_behind).c_str(), new_weight ); | ||
if (new_weight < dist[new_index][new_behind]) { | ||
dist[new_index][new_behind] = new_weight; | ||
q.push( pack(new_index, new_behind, new_weight) ); | ||
//printf(" That's better.\n"); | ||
} | ||
} | ||
} | ||
|
||
} | ||
return -1; | ||
} | ||
|
||
int main(){ | ||
while (cin >> n) { | ||
if (n == 0) break; | ||
for (int i = 0; i < n; ++i) cin >> words[i]; | ||
int ans = search(); | ||
cout << ans << endl; | ||
} | ||
return 0; | ||
} |
Binary file not shown.
Oops, something went wrong.