Skip to content

Commit

Permalink
3930 - Drop the Triples (DP) && 3972 - March of the penguins (Grafos,…
Browse files Browse the repository at this point in the history
… máximo flujo, Ford-Fulkerson, Edmonds-Karp)
  • Loading branch information
Familia committed Sep 30, 2008
1 parent 79b4577 commit 775e225
Show file tree
Hide file tree
Showing 52 changed files with 7,577 additions and 0 deletions.
Binary file added 3169 - Boundary points/3169.2
Binary file not shown.
125 changes: 125 additions & 0 deletions 3169 - Boundary points/3169.2.cpp
@@ -0,0 +1,125 @@
/*
Problem: 3169 - Boundary points
Algorithm: Convex hull; Graham Scan
Author: Andrés Mejía-Posada
Accepted
*/

#include <algorithm>
#include <iostream>
#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 <map>
#include <set>
using namespace std;

struct point {
double x, y;
point(){} point(double x, double y) : x(x), y(y) {}
bool operator <(const point &p) const {
return x < p.x || (x == p.x && y < p.y);
}
};

point pivot;

ostream& operator<< (ostream& out, const point& c)
{
out << "(" << c.x << "," << c.y << ")";
return out;
}

inline double distsqr(const point &a, const point &b){
return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}

inline double dist(const point &a, const point &b){
return sqrt(distsqr(a, b));
}


// 2D cross product.
// Return a positive value, if ABC makes a counter-clockwise turn,
// negative for clockwise turn, and zero if the points are collinear.
double cross(const point &a, const point &b, const point &c){
double d = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
if (fabs(d) < 1e-9) return 0.0;
return d;
}



//Self < that si esta a la derecha del segmento Pivot-That
bool angleCmp(const point &self, const point &that){
double t = cross(pivot, that, self);
if (t < 0.0) return true;
if (t == 0){
//Self < that si está más cerquita
return (distsqr(pivot, self) < distsqr(pivot, that));
}
return false;
}

//vector p tiene los puntos ordenados anticlockwise
vector<point> graham(vector<point> p){
//Metemos el más abajo más a la izquierda en la posición 0
for (int i=1; i<p.size(); ++i){
if (p[i].y < p[0].y || (p[i].y == p[0].y && p[i].x < p[0].x ))
swap(p[0], p[i]);
}

pivot = p[0];
sort(p.begin(), p.end(), angleCmp);

//Ordenar por ángulo y eliminar repetidos.
//Si varios puntos tienen el mismo angulo el más lejano queda después en la lista
vector<point> chull(p.begin(), p.begin()+3);

//Ahora sí!!!
for (int i=3; i<p.size(); ++i){
while ( chull.size() >= 2 && cross(chull[chull.size()-2], chull[chull.size()-1], p[i]) <= 0){
chull.erase(chull.end() - 1);
}
chull.push_back(p[i]);
}

return chull;
}

int main(){
string s;
while (getline(cin, s)){
stringstream splitter(s);
string pnt;
vector<point> poly;
while (splitter >> pnt){
assert(pnt.size() > 3);
pnt[0] = pnt[pnt.size()-1] = pnt[pnt.find(',')] = ' ';
stringstream sin(pnt);
double x, y;
sin >> x >> y;
poly.push_back(point(x, y));
}

vector<point> ans = graham(poly);
ans.push_back(ans[0]);
cout << "(" << ans.front().x << "," << ans.front().y << ")";
for (int i=1; i<ans.size(); ++i){
cout << " (" << ans[i].x << "," << ans[i].y << ")";
}
cout << endl;
}
return 0;
}
1 change: 1 addition & 0 deletions 3169 - Boundary points/3169.cpp
@@ -1,5 +1,6 @@
/*
Problem: 3169 - Boundary points
Algorithm: Convex hull; Andrew's monotone chain.
Author: Andrés Mejía-Posada
*/

Expand Down
1 change: 1 addition & 0 deletions 3169 - Boundary points/in.txt
@@ -1 +1,2 @@
(-2,1) (-1,-2) (-1,1) (-1,2) (-1,3) (0,0) (1,-1) (1,1) (2,-2) (2,1) (3,2)
(0,0) (0.5,0) (1,0) (1,0.5) (1,1) (0.5,1) (0,1) (0.5,0.5) (0,0) (1,1) (0.3,0.7)
1 change: 1 addition & 0 deletions 3170 - AGTC/3170.cpp
@@ -1,5 +1,6 @@
/*
Problem: 3170 - AGTC
Algorithm: Levenshtein algorithm
Author: Andrés Mejía-Posada
*/

Expand Down
1 change: 1 addition & 0 deletions 3171 - Oreon/3171.cpp
@@ -1,5 +1,6 @@
/*
Problem: 3171 - Oreon
Algorithm: Minimum spanning tree; Kruskal's algorithm
Author: Andrés Mejía-Posada
*/

Expand Down
1 change: 1 addition & 0 deletions 3173 - Wordfish/3173.cpp
@@ -1,5 +1,6 @@
/*
Problem: 3173 - Wordfish
Algorithm: Ad-hoc
Author: Andrés Mejía-Posada
*/

Expand Down
Binary file added 3639 - Prime path/3639.2
Binary file not shown.
93 changes: 93 additions & 0 deletions 3639 - Prime path/3639.2.cpp
@@ -0,0 +1,93 @@
/*
Problem: 3639 - Prime Path (ACM-ICPC Live Archive)
Andrés Mejía-Posada
Verdict: Accepted.
Algorithm: BFS and Eratosthenes' sieve.
Version 2 = Version 1 + A little faster sieve
*/
#include <iostream>
#include <cassert>
#include <queue>

using namespace std;



const int SIZE = 9999;

//criba[i] = false si i es primo
bool criba[SIZE+1];

void buildCriba(){
memset(criba, false, sizeof(criba));

criba[0] = criba[1] = true;
for (int i=4; i<=SIZE; i += 2){
criba[i] = true;
}
for (int i=3; i*i<=SIZE; i += 2){
if (!criba[i]){
for (int j=i*i; j<=SIZE; j += i){
criba[j] = true;
}
}
}
}

int main(){
buildCriba();
int c;
cin >> c;
while (c--){
int start, end;
cin >> start >> end;
bool visited[SIZE+1] = {false};
queue<pair<int, int> > q;
q.push(make_pair(0, start));

int answer = -1;

while (q.size()){
int u = q.front().second;
int w = q.front().first;
q.pop();

//cout << "Saque " << u << " en " << w << endl;

if (1000 <= u && u <= 9999 && !criba[u] && !visited[u]){
visited[u] = true;

if (u == end){
answer = w;
break;
}

for (int i=1; i<=4; ++i){
int pow10 = 1; for (int j=1; j<=i; ++j) pow10 *= 10;
int digit = (u % pow10)* 10/pow10;

int v = u - digit * pow10/10;
for (int k=0; k<=9; ++k){
int possible = v + pow10/10 * k;
if (1000 <= possible && possible <= 9999 && !criba[possible] && !visited[possible]){
assert(possible % 2 == 1);
q.push(make_pair(w + 1, possible));
//cout << " Meti " << possible << endl;
}
}
}
}
}
if (answer == -1){
cout << "Impossible" << endl;
}else{
cout << answer << endl;
}
}

return 0;
}
Binary file added 3930 - Drop the Triples/3930
Binary file not shown.
Binary file added 3930 - Drop the Triples/3930.2
Binary file not shown.
91 changes: 91 additions & 0 deletions 3930 - Drop the Triples/3930.2.cpp
@@ -0,0 +1,91 @@
/*
Problem: 3930 - Drop the Triples
Author: Andrés Mejía-Posada
*/

#include <algorithm>
#include <iostream>
#include <iterator>
#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 <map>
#include <set>
using namespace std;

#define V(x) cout << #x " is: "; if (x.size() > 0 ) copy(x.begin(), x.end(), ostream_iterator<typeof(x[0])>(cout, " ")); cout << endl

int ans;
deque<int> so_far;

void backtrack(int used, const vector<int> &x){
int m = so_far.size(), n = x.size();
ans >?= m/3;

for (int i=0; i<n; ++i){
if (!(used & (1 << i))){
if (m%3==0 || (x[i] >= so_far[m-1] && (m%3==1 || (m%3==2 && so_far[m-2] + so_far[m-1] > x[i])))){
so_far.push_back(x[i]);
backtrack(used | (1 << i), x);
so_far.pop_back();
}
}
}

}

int common(const vector<int> &x){
so_far.clear();
ans = 0;
backtrack(0, x);
return ans;
}


int main(){
int n, C=1;
while(cin>>n &&n){
cerr << C++ << endl;
vector<int> a(14, 0), b(14, 0);
for (int i=0; i<n; ++i){
int x;
cin >> x;
if (i%2) b[x]++;
else a[x]++;
}
int pa = 0, pb = 0;
for (int i=1; i<=13; ++i){
while (a[i] >= 3) a[i]-=3, pa++;
while (b[i] >= 3) b[i]-=3, pb++;
}

if (pa != pb){
cout << (pa > pb ? "1" : "2") << endl;
}else{
int ca = 0, cb = 0;
vector<int> xa, xb;
for (int i=1; i<=13; ++i){
while (a[i]--) xa.push_back(i);
while (b[i]--) xb.push_back(i);
}

//V(xa); V(xb);

ca = common(xa), cb = common(xb);
if (ca == cb) cout << "0\n";
else cout << (ca > cb ? "1" : "2") << endl;

}
}
return 0;
}
Binary file added 3930 - Drop the Triples/3930.3
Binary file not shown.

0 comments on commit 775e225

Please sign in to comment.