算法分析与设计课POJ作业(1~4章)
记录一下,方便日后查看
第一章
POJ-3487 稳定匹配
传送门:The Stable Marriage Problem
模板题
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 30;
int t, n;
int boy[30][30], girl[30][30];
int bcho[30], gcho[30];
int bname[30], gname[30];
string str;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while (t--) {
cin >> n;
queue<int> q;
for (int i = 0; i < n; i++) {
cin >> str;
bname[i] = str[0] - 'a';
q.push(bname[i]);
}
sort(bname, bname + n);
for (int i = 0; i < n; i++) {
cin >> str;
gname[i] = str[0] - 'A';
}
for (int i = 0; i < n; i++) {
cin >> str;
for (int j = 0; j < n; j++)
boy[i][j] = str[j + 2] - 'A';
}
memset(girl, 100, sizeof(girl));
for (int i = 0; i < n; i++) {
cin >> str;
for (int j = 0; j < n; j++)
girl[i][str[j + 2] - 'a'] = j - 2;
}
memset(bcho, 0, sizeof(bcho));
for (int i = 0; i < n; i++)
gcho[i] = n;
while (!q.empty()) {
int now = q.front();
int ele = boy[now][bcho[now]];
if (girl[ele][now] < girl[ele][gcho[ele]]) {
q.pop();
if (gcho[ele] != n) {
q.push(gcho[ele]);
bcho[gcho[ele]]++;
}
gcho[ele] = now;
} else bcho[now]++;
}
for (int i = 0; i < n; i++) cout << (char)(bname[i] + 'a') << " " << (char)(boy[bname[i]][bcho[bname[i]]] + 'A') << endl;
cout << endl;
}
return 0;
}
POJ-3970 最小公倍数
传送门:Party
模板题
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
#define ll long long
int n;
ll ans, num;
inline ll gcd(ll a, ll b) {
return a % b == 0 ? b : gcd(b, a % b);
}
int main() {
while (cin >> n && n != 0) {
cin >> ans; n--;
while (n--) {
cin >> num;
ans = ans * num / gcd(ans, num);
}
if (ans >= 1000000) cout << "Too much money to pay!" << endl;
else cout << "The CEO must bring " << ans << " pounds." << endl;
}
return 0;
}
第二章
POJ-1995 快速幂
模板题
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int t, n, p, x, y, ans;
inline int cal(int a, int b, int mod) {
int cnt = 1;
while (b > 0) {
if (b & 1) cnt = cnt * a % mod;
a = (a % mod) * (a % mod) % mod;
b >>= 1;
}
return cnt;
}
int main() {
cin >> t;
while (t--) {
cin >> p >> n; ans = 0;
for (int i = 1; i <= n; i++) {
cin >> x >> y;
ans = (ans + cal(x, y, p)) % p;
}
cout << ans << endl;
}
return 0;
}
POJ-2092 计数排序
我与 cin 不共戴天,疯狂 TLE 把我整蒙了,改成 scanf 就过了
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#pragma GCC optimize(2)
using namespace std;
const int maxn = 1e4 + 10;
int n, m;
struct node{
int x, y;
}e[maxn * 2];
inline bool cmp(node a, node b) {
if (a.y == b.y) return a.x < b.x;
return a.y > b.y;
}
int main() {
while (scanf("%d%d", &n, &m)) {
if (n == 0 && m == 0) break;
map<int, int> mp;
int cnt = 1;
memset(e, 0, sizeof(e));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
register int x; scanf("%d", &x);
if (mp[x] == 0) {
mp[x] = cnt;
e[cnt].x = x; e[cnt].y++;
cnt++;
} else e[mp[x]].y++;
}
sort(e + 1, e + cnt + 1, cmp);
int num = 2;
while (e[num].y == e[1].y) num++;
int now = num;
while (e[now].y == e[num].y) {
printf("%d ", e[now].x);
now++;
}
printf("\n");
}
return 0;
}
POJ-2503 快速查找
传送门:Babelfish
快速查找个锤子,map 直接过
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int maxn = 101;
map<string, string> mp;
char s[maxn], a[maxn], b[maxn];
int main() {
while (gets(s) && s[0] != '\0') {
sscanf(s, "%s %s", a, b);
mp[b] = a;
}
while (gets(s)) {
if (mp.find(s) != mp.end()) cout << mp[s] << endl;
else cout << "eh" << endl;
}
return 0;
}
第三章
POJ-3061 尺取法
传送门:Subsequence
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1e5 + 10;
int t, n, s;
int a[maxn];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &s);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
int l = 1, r = 2;
int ans = 0x7fffffff;
int num = a[1] + a[2];
while (r <= n) {
while (num >= s) {
ans = min(ans, r - l + 1);
num -= a[l++];
}
num += a[++r];
}
if (ans == 0x7fffffff) printf("0\n");
else printf("%d\n", ans);
}
return 0;
}
POJ-2785 折半+枚举
二分
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 4010;
int n, cnt1, cnt2, ans;
int a[maxn], b[maxn], c[maxn], d[maxn];
int sum1[maxn * maxn], sum2[maxn * maxn];
int check(int x) {
int l = 1, r = cnt2;
while (l <= r) {
int mid = (l + r) >> 1;
if (x + sum2[mid] == 0) {
int now = mid, num = 0;
while (x + sum2[now] == 0 && now <= cnt2)
now++, num++;
now = mid - 1;
while (x + sum2[now] == 0 && now >= 1)
now--, num++;
return num;
} else if (x + sum2[mid] > 0) r = mid - 1;
else l = mid + 1;
}
return 0;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
sum1[++cnt1] = a[i] + b[j];
sum2[++cnt2] = c[i] + d[j];
}
sort(sum2 + 1, sum2 + cnt2 + 1);
for (int i = 1; i <= cnt1; i++)
ans += check(sum1[i]);
printf("%d\n", ans);
return 0;
}
POJ-1256 排列
传送门:Anagram
直接用 next_permutation
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n, len;
char s[15];
bool cmp(char a, char b) {
if (tolower(a) == tolower(b)) return a < b;
else return tolower(a) < tolower(b);
}
int main() {
scanf("%d", &n);
getchar();
while (n--) {
gets(s);
len = strlen(s);
sort(s, s + len, cmp);
do printf("%s\n", s);
while (next_permutation(s, s + len, cmp));
}
return 0;
}
第四章
POJ-3262 牛吃花
贪心
#include <cstdio>
#include <cmath>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int n;
long long ans, num;
struct node{
int t, d;
}a[maxn * 2];
bool cmp(node x, node y) {
return (x.t * 1.0 / x.d) < (y.t * 1.0 / y.d);
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf ("%d%d", &a[i].t, &a[i].d);
sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
ans += a[i].d * num;
num += a[i].t * 2;
}
printf("%lld\n", ans);
return 0;
}
POJ-3268 最短路1
传送门:Silver Cow Party
跑两趟 dijkstra
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
const int maxn = 1e5 + 10;
int n, m, x, cnt, ans;
int head[maxn], dis[maxn], vis[maxn];
struct edge{
int to, nxt, dis;
}e[maxn * 3];
priority_queue< pair<int, int> >q;
void add(int u, int v, int w) {
e[++cnt].to = v;
e[cnt].nxt = head[u];
e[cnt].dis = w;
head[u] = cnt;
}
void dijkstra(int s) {
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) dis[i] = INF;
dis[s] = 0;
q.push(make_pair(0, s));
while (q.size()) {
int u = q.top().second;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
int w = e[i].dis;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push(make_pair(-dis[v], v));
}
}
}
}
int main() {
scanf("%d%d%d", &n, &m, &x);
for (int i = 1; i <= m; i++) {
register int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
dijkstra(x);
vector<int> dd(dis + 1, dis + 1 + n);
for (int i = 1; i <= n; i++) {
dijkstra(i);
ans = max(ans, dis[x] + dd[i - 1]);
}
printf("%d\n", ans);
return 0;
}
POJ-3463 最短路2
传送门:Sightseeing
求最短路和次短路
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e4 + 10;
int t, n, m, cnt, s, f;
int head[maxn], dis[maxn][5], vis[maxn][5], num[maxn][5];
struct node{
int v, w, nxt;
}e[maxn * 3];
struct edge{
int v, d, tg;
edge(int v, int d, int tg):v(v), d(d), tg(tg) {
}
bool operator < (const edge &x)const {
return d > x.d;
}
};
inline void init() {
cnt = 0;
memset(head, 0, sizeof(head));
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
}
inline void add(int u, int v, int w) {
e[++cnt].v = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt;
}
inline void dijkstra() {
num[s][0] = 1; dis[s][0] = 0;
priority_queue<edge> q;
q.push(edge(s, 0, 0));
while (!q.empty()) {
edge tmp = q.top(); q.pop();
int u = tmp.v, tg = tmp.tg;
if (vis[u][tg]) continue;
vis[u][tg] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].v, w = e[i].w;
if (dis[v][0] > w + tmp.d) {
if (dis[v][0] != 0x3f) {
dis[v][1] = dis[v][0];
num[v][1] = num[v][0];
q.push(edge(v, dis[v][1], 1));
}
dis[v][0] = w + tmp.d;
num[v][0] = num[u][tg];
q.push(edge(v, dis[v][0], 0));
} else if (dis[v][0] == w + tmp.d) {
num[v][0] += num[u][tg];
} else if (dis[v][1] > w + tmp.d) {
dis[v][1] = w +tmp.d;
num[v][1] = num[u][tg];
q.push(edge(v, dis[v][1], 1));
} else if (dis[v][1] == w + tmp.d) {
num[v][1] += num[u][tg];
}
}
}
}
int main() {
scanf("%d", &t);
while (t--) {
init();
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
register int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
scanf("%d%d", &s, &f);
dijkstra();
if (dis[f][1] - dis[f][0] == 1)
printf("%d\n", num[f][0] + num[f][1]);
else printf("%d\n", num[f][0]);
}
return 0;
}
POJ-3069 区间调度
传送门:Saruman's Army
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
const int maxn = 1010;
int r, n, ans, now, a[maxn];
int main() {
while (scanf("%d%d", &r, &n)) {
if (r == -1 && n == -1) break;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
ans = 0; now = 1;
while (now <= n) {
int num = a[now++];
while (now <= n && a[now] <= num + r) now++;
ans++;
num = a[now - 1];
while (now <= n && a[now] <= num + r) now++;
}
cout << ans << endl;
}
return 0;
}
POJ-1328 区间选点
贪心
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1e7 + 10;
struct node{
double l, r;
}poi[maxn];
int n, d;
double x, y;
inline bool cmp(node a, node b) {
return a.l < b.l;
}
int main() {
int cnt = 0;
while (scanf("%d%d", &n, &d) != EOF) {
if (n == 0 && d == 0) break;
bool flag = false;
for (int i = 1; i <= n; i++) {
scanf("%lf%lf", &x, &y);
if (y > d) flag = true;
poi[i].l = x - sqrt(d * d - y * y);
poi[i].r = x + sqrt(d * d - y * y);
}
if (flag) {
printf("Case %d: -1\n", ++cnt);
continue;
}
sort(poi + 1, poi + 1 + n, cmp);
double now = poi[1].r;
int ans = 1;
for (int i = 2; i <= n; i++) {
if (poi[i].l <= now) now = min(now, poi[i].r);
else {
now = poi[i].r;
ans++;
}
}
printf("Case %d: %d\n", ++cnt, ans);
}
return 0;
}
POJ-2376 区间覆盖
传送门:Cleaning Shifts
贪心
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
const int maxn = 1e7 + 10;
struct node{
int l, r;
}poi[maxn];
int ans;
int n, t;
inline bool cmp(node a, node b) {
if (a.l == b.l) return a.r > b.r;
return a.l < b.l;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> t;
for (int i = 1; i <= n; i++)
cin >> poi[i].l >> poi[i].r;
sort(poi + 1, poi + 1 + n, cmp);
int left, right = 0, i = 1;
while (right < t) {
left = right + 1;
for (; i <= n; i++)
if (poi[i].l <= left) right = max(right, poi[i].r);
else break;
if (right < left) {
ans = -1; break;
}
ans++;
}
cout << ans << endl;
return 0;
}
POJ-3190 区间划分
贪心
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
const int maxn = 1e7 + 10;
int n, ans = 1, vis[maxn];
struct node{
int st, en, pos;
}a[maxn], now;
struct cmpp{
bool operator ()(node &a, node &b) {
return a.en > b.en;
}
};
priority_queue<node, vector<node>, cmpp> q;
inline bool cmp(node x, node y) {
if (x.st == y.st) return x.en < y.en;
return x.st < y.st;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].st, &a[i].en);
a[i].pos = i;
}
sort(a + 1, a + 1 + n, cmp);
q.push(a[1]);
vis[a[1].pos] = 1;
for (int i = 2; i <= n; i++) {
if (!q.empty()) {
now = q.top();
if (now.en < a[i].st) {
vis[a[i].pos] = vis[now.pos];
q.pop();
} else {
ans++;
vis[a[i].pos] = ans;
}
}
q.push(a[i]);
}
printf("%d\n", ans);
for (int i = 1; i <= n; i++) printf("%d\n", vis[i]);
return 0;
}
POJ-1789 Kruskal
传送门:Truck History
模板题
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 2005;
int n, cnt, ans, fa[maxn];
char s[maxn][7];
struct node{
int u, v, len;
}e[maxn * (maxn >> 1)];
inline void add(int x, int y, int z) {
e[++cnt].u = x;
e[cnt].v = y;
e[cnt].len = z;
}
inline bool cmp(node x, node y) {
return x.len < y.len;
}
inline void init() {
cnt = 0; ans = 0;
for (int i = 0; i <= n; i++) fa[i] = i;
}
inline int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
inline void kruskal() {
for (int i = 1; i <= cnt; i++) {
int u = find(e[i].u), v = find(e[i].v);
if (u != v) {
fa[u] = v;
ans += e[i].len;
}
}
}
int main() {
while (~scanf("%d", &n) && n) {
init();
for (int i = 1; i <= n; i++) scanf("%s", s[i]);
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) {
int nummm = 0;
for (int k = 0; k < 7; k++)
if (s[i][k] != s[j][k]) nummm++;
add(i, j, nummm);
}
sort(e + 1, e + 1 + cnt, cmp);
kruskal();
printf("The highest possible quality is 1/%d.\n", ans);
}
return 0;
}
POJ-1258 Prim
传送门:Agri-Net
模板题
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#define INF 1e7 + 1
using namespace std;
const int maxn = 110;
int n;
int cost[maxn][maxn], mincost[maxn];
bool vis[maxn];
inline void init() {
for (int i = 0; i <= maxn; i++)
for (int j = 0; j <= maxn; j++)
if (i == j) cost[i][j] = 0;
else cost[i][j] = INF;
}
inline int prim() {
for (int i = 1; i <= n; ++i) {
mincost[i] = INF;
vis[i] = false;
}
mincost[1] = 0;
int res = 0;
while (1) {
int num = -1;
for (int i = 1; i <= n; i++)
if (!vis[i] && (num == -1 || mincost[i] < mincost[num]))
num = i;
if (num == -1) break;
vis[num] = true;
res += mincost[num];
for (int i = 1; i <= n; i++)
mincost[i] = min(mincost[i], cost[num][i]);
}
return res;
}
signed main() {
ios::sync_with_stdio(false);
while (cin >> n) {
init();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) cin >> cost[i][j];
cout << prim() << endl;
}
return 0;
}
POJ-1521 哈夫曼编码
传送门:Entropy
优先队列
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e3 + 10;
char s[maxn];
int a[27], ans;
int main() {
while (scanf("%s", s)) {
int len = strlen(s);
if (len == 3 && s[0] == 'E' && s[1] == 'N' && s[2] == 'D') break;
memset(a, 0, sizeof(a));
for (int i = 0; i < len; i++)
if (s[i] >= 'A' && s[i] <= 'Z') a[s[i] - 'A']++;
else if (s[i] == '_') a[26]++;
priority_queue<int, vector<int>, greater<int> > q;
for (int i = 0; i < 27; i++) {
if (a[i] == 0) continue;
q.push(a[i]);
}
ans = 0;
if (q.size() == 1) {
ans = q.top();
printf("%d %d %.1lf\n", len * 8, ans, (len * 8.0) / (1.0 * ans));
} else {
while (q.size() >= 2) {
int num1 = q.top(); q.pop();
int num2 = q.top(); q.pop();
ans += num1 + num2;
q.push(num1 + num2);
}
printf("%d %d %.1lf\n", len * 8, ans, (len * 8.0) / (1.0 * ans));
}
}
return 0;
}
POJ-1042 钓鱼问题
传送门:Gone Fishing
贪心
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e4 + 10;
int m, n, cnt, maxcnt;
int fish[maxn], d[maxn], leftfish[maxn], t[maxn], stay[maxn], tmp[maxn];
int main() {
while (scanf("%d", &n) != EOF) {
if (n == 0) break;
scanf("%d", &m);
m *= 60;
for (int i = 1; i <= n; i++) scanf("%d", &fish[i]);
for (int i = 1; i <= n; i++) scanf("%d", &d[i]);
for (int i = 1; i < n; i++) {
scanf("%d", &t[i]);
t[i] *= 5;
}
memset(stay, 0, sizeof(stay));
maxcnt = -1;
int timeroad = 0, timefish = m;
for (int i = 1; i <= n; i++) {
cnt = 0;
memset(tmp, 0, sizeof(tmp));
timefish = m - timeroad;
for (int j = 1; j <= n; j++) leftfish[j] = fish[j];
while (1) {
if (timefish < 5) break;
int num = -1, id;
for (int j = 1; j <= i; j++)
if (leftfish[j] > num) {
num = leftfish[j];
id = j;
}
if (num == 0) {
tmp[1] += timefish / 5 * 5;
break;
}
tmp[id] += 5;
cnt += leftfish[id];
leftfish[id] -= d[id];
if (leftfish[id] < 0) leftfish[id] = 0;
timefish -= 5;
}
if (cnt > maxcnt) {
maxcnt = cnt;
for (int j = 1; j <= n; j++) stay[j] = tmp[j];
} else if (cnt == maxcnt) {
for (int j = 1; j <= n; j++) {
if (tmp[j] < stay[j]) break;
if (tmp[j] > stay[j])
for (int k = 1; k <= n; k++) stay[k] = tmp[k];
}
}
timeroad += t[i];
if (timeroad > m) break;
}
cout << stay[1];
for (int i = 2; i <= n; ++i) cout << ", " << stay[i];
cout << endl << "Number of fish expected: " << maxcnt << endl << endl;
}
return 0;
}