藍橋杯題庫 算法提高非vip部分(C++、Java)代碼實現(251-280)

將定期更新藍橋杯習題集的解題報告~

ADV-251 Petri Net Simulation

cpp:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

const int maxn = 105;

int p, t, np[maxn], lim;

struct petri {
    int ip, op, i[maxn], o[maxn], in[maxn], out[maxn];
} pet[maxn];
// ip、op是參與變遷的place的編號

int main() {
    int kase = 0;
    while (scanf("%d", &p) && p) {
        memset(pet, 0, sizeof(pet));
        for (int i = 1; i <= p; ++i) {
            scanf("%d", &np[i]);
        }
        scanf("%d", &t);
        for (int i = 1; i <= t; ++i) {
            int k;
            while (scanf("%d", &k), k) {
                if (k < 0) {
                    ++pet[i].in[-k];
                } else {
                    ++pet[i].out[k];
                }
            }
            for (int j = 1; j <= p; ++j) {
                if (pet[i].in[j]) {
                    pet[i].i[++pet[i].ip] = j;
                }
                if (pet[i].out[j]) {
                    pet[i].o[++pet[i].op] = j;
                }
            }
        }
        scanf("%d", &lim);
        int cnt = 0;
        for (int i = 1; i <= t; ++i) {
            bool flag = true;
            petri &k = pet[i];
            for (int j = 1; j <= k.ip; ++j) {
                if (np[k.i[j]] < k.in[k.i[j]]) {
                    flag = false;
                    break;
                }
            }
            if (!flag) continue;
            for (int j = 1; j <= k.ip; ++j) {
                np[k.i[j]] -= k.in[k.i[j]];
            }
            for (int j = 1; j <= k.op; ++j) {
                np[k.o[j]] += k.out[k.o[j]];
            }
            i = 0;
            if (++cnt >= lim) break;
        }
        if (cnt >= lim) {
            printf("Case %d: still live after %d transitions\n", ++kase, lim);
        } else {
            printf("Case %d: dead after %d transitions\n", ++kase, cnt);
        }
        printf("Places with tokens:");
        for (int i = 1; i <= p; ++i) {
            if (np[i]) {
                printf(" %d (%d)", i, np[i]);
            }
        }
        printf("\n\n");
    }
    return 0;
}

java:

import java.util.*;
public class Main {
	static int np, nt, nf;
	static int p[], in[][], out[][];
	static int cur;
	static int enabled() {
		for(int i=0; i<nt; i++) {
			boolean flag = true;
			for(int j=0; j<np; j++) 
				if(p[j] < in[i][j]) {
					flag = false;
					break;
				}
			if(flag)
				return i;
		}
		return -1;
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int t = 0;
		while(true) {
			t++;
			cur = 0;
			np = sc.nextInt();
			if(np==0)
				break;
			p = new int[np];
			for(int i=0; i<np; i++) {
				p[i] = sc.nextInt();
			}
			nt = sc.nextInt();
			in = new int[nt][np];
			out = new int[nt][np];
			for(int i=0; i<nt; i++) {
				for(int j=0; ; j++) {
					int n = sc.nextInt();
					if(n==0)
						break;
					else if(n<0)
						in[i][-n-1] ++;
					else
						out[i][n-1] ++;
				}
			}
			nf = sc.nextInt();
			while(true) {
				int n = enabled();
				if(n==-1||cur==nf)
					break;	
				for(int j=0; j<np; j++) {
					p[j] -= in[n][j];
					p[j] += out[n][j];
				}
				cur++;
			}	
			if(enabled()!=-1) {
				System.out.println("Case "+t+": still live after "+cur+" transitions");
			}else {
				System.out.println("Case "+t+": dead after "+cur+" transitions");
			}
			System.out.print("Places with tokens:");
			for(int i=0; i<np; i++) {
				if(p[i]>=1) 
					System.out.print(" "+(i+1)+" ("+p[i]+")");
			}
			System.out.println("\n");
		}
	}
}

ADV-252 Navigation

cpp:

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

struct SD {
    float x, y, r;
} sd[10];

struct Dot {
    float x, y, d;
    bool flag;
} dot[2];

int n;  //輸出時的參數

float distance(float x1, float y1, float x2, float y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int belong(int x, int y) {
    if (fabs(sd[x].r - distance(sd[x].x, sd[x].y, dot[y].x, dot[y].y)) < 0.1)
        return 1;
    else
        dot[y].flag = false;
    return 0;
}

void find_dot(int x, int y) {
    float a, b, c, p, q, s, rx, ry, t[2];
    int i;
    rx = sd[x].x - sd[y].x;
    ry = sd[x].y - sd[y].y;
    a = 2 * sd[x].r * rx;
    b = 2 * sd[x].r * ry;
    c = sd[y].r * sd[y].r - sd[x].r * sd[x].r - rx * rx - ry * ry;
    p = a * a + b * b;
    q = -2 * a * c;
    s = c * c - b * b;
    t[0] = (sqrt(q * q - 4 * p * s) - q) / (2 * p);
    t[1] = (-sqrt(q * q - 4 * p * s) - q) / (2 * p);
    if (n == 2) {
        for (i = 0; i < 2; i++) {
            dot[i].d = asin(t[i]);
            dot[i].x = sd[x].x + sd[x].r * sin(dot[i].d);
            dot[i].y = sd[x].y + sd[x].r * cos(dot[i].d);
            if (belong(x, i) && belong(y, i)) dot[i].flag = true;
        }
        for (i = 0; i < 2; i++) {
            if (dot[i].flag == false) {
                dot[i].d = asin(t[i]);
                dot[i].x = sd[x].x + sd[x].r * sin(dot[i].d);
                dot[i].y = sd[x].y - sd[x].r * cos(dot[i].d);
                dot[i].flag = true;
            }
        }
    } else {
        dot[0].d = asin(t[0]);
        dot[0].x = sd[x].x + sd[x].r * sin(dot[0].d);
        dot[0].y = sd[x].y + sd[x].r * cos(dot[0].d);
        if (!(belong(x, 0) && belong(y, 0))) {
            dot[0].d = asin(-t[0]);
            dot[0].x = sd[x].x + sd[x].r * sin(dot[0].d);
            dot[0].y = sd[x].y + sd[x].r * cos(dot[0].d);
        }
    }
}

int main() {
    int N;  //信號源數量
    int i, j;
    float tx, ty, rt;
    float t1 = -1, t2 = -1;
    float td;
    int d = 0;
    int k = 0;
    int a[10], b[10];

    do {
        n = -2;
        scanf("%d %f %f %f", &N, &rt, &tx, &ty);
        for (i = 0; i < N; i++) {
            float sx, sy, st, d;
            scanf("%f %f %f %f", &sx, &sy, &d, &st);
            sd[i].x = sx + 100.0 * sin(d * 3.1415926 / 180) * st;
            sd[i].y = sy + 100.0 * cos(d * 3.1415926 / 180) * st;
            sd[i].r = (rt - st) * 350.0;
        }

        dot[0].flag = false;
        dot[1].flag = false;

        if (N == 1) n = -1;

        for (i = 0; i < N; i++)
            for (j = i + 1; j < N; j++) {
                if ((distance(sd[i].x, sd[i].y, sd[j].x, sd[j].y) - sd[i].r -
                     sd[j].r) < -0.1) {
                    t1 = i;
                    t2 = j;
                    n = 2;
                    break;
                }
            }

        if (n == -2) {
            for (i = 0; i < N; i++)
                for (j = i + 1; j < N; j++) {
                    if (fabs(distance(sd[i].x, sd[i].y, sd[j].x, sd[j].y) -
                             sd[i].r - sd[j].r) < 0.1) {
                        t1 = i;
                        t2 = j;
                        n = 1;
                        break;
                    }
                }
        }

        if (n == 1 || n == 2) {
            find_dot(t1, t2);
            for (i = 0; i < N; i++)
                if (i != t1 && i != t2)
                    for (j = 0; (j < 2) && (dot[j].flag == true); j++) {
                        if (!belong(i, j)) {
                            n--;
                        }
                        if (n == 0) break;
                    }
        }

        if (n == 1) {
            for (i = 0; i < 2; i++) {
                if (dot[i].flag == true)
                    if (distance(tx, ty, dot[i].x, dot[i].y) < 0.1)
                        n = 3;
                    else {
                        td = atan(fabs((dot[i].y - ty) / (dot[i].x - tx))) *
                             57.3;
                        d = (int)(td + 0.5);
                        if (tx > dot[i].x && ty < dot[i].y)
                            d += 90;
                        else if (tx < dot[i].x && ty < dot[i].y)
                            d = 270 - d;
                        else if (tx < dot[i].x && ty > dot[i].y)
                            d += 270;
                        else if (tx > dot[i].x && ty > dot[i].y)
                            d = 90 - d;
                    }
            }
        }

        a[k] = n;
        b[k++] = d;
    } while (N != 0);

    for (i = 0; i < k - 1; i++) {
        printf("Trial %d: ", i + 1);
        switch (a[i]) {
            case -1:
                printf("Inconclusive");
                break;
            case 0:
                printf("Inconsistent");
                break;
            case 1:
                printf("%d degrees", b[i]);
                break;
            case 2:
                printf("Inconclusive");
                break;
            case 3:
                printf("Arrived");
        }
        printf("\n");
    }
    return 0;
}

ADV-256 The Sky is the Limit

cpp:

#include <algorithm>
#include <complex>
#include <cstdio>
using namespace std;

typedef long double db;
typedef complex<db> Point;
typedef Point Vector;

int n, a[105], b[105], c[105], cn;
db cut[25005], rx, ans;

db Cross(Vector A, Vector B) { return imag(conj(A) * B); }

bool get_Cross(db px, db py, db qx, db qy, db p2x, db p2y, db q2x, db q2y) {
    Point P = (Point){px, py};
    Vector v = (Vector){qx - px, qy - py};
    Point Q = (Point){p2x, p2y};
    Vector w = (Vector){q2x - p2x, q2y - p2y};
    Vector u = P - Q;
    if (Cross(v, w) == 0) return false;
    db t = Cross(w, u) / Cross(v, w);
    rx = (P + v * t).real();
    if (rx < min(px, qx) || rx > max(px, qx)) return false;
    if (rx < min(p2x, q2x) || rx > max(p2x, q2x)) return false;
    return true;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d", &a[i], &b[i], &c[i]);
        cut[++cn] = a[i] - c[i] / 2.0, cut[++cn] = a[i] + c[i] / 2.0,
        cut[++cn] = a[i];
    }
    for (int i = 1; i < n; i++)
        for (int j = i + 1; j <= n; j++) {
            db o = a[i] - c[i] / 2.0, p = a[i] + c[i] / 2.0,
               q = a[j] - c[j] / 2.0, r = a[j] + c[j] / 2.0;
            if (get_Cross(o, 0, a[i], b[i], q, 0, a[j], b[j])) cut[++cn] = rx;
            if (get_Cross(o, 0, a[i], b[i], a[j], b[j], r, 0)) cut[++cn] = rx;
            if (get_Cross(a[i], b[i], p, 0, q, 0, a[j], b[j])) cut[++cn] = rx;
            if (get_Cross(a[i], b[i], p, 0, a[j], b[j], r, 0)) cut[++cn] = rx;
        }
    sort(cut + 1, cut + cn + 1);
    cn = unique(cut + 1, cut + cn + 1) - cut - 1;
    for (int i = 1, pos; i < cn; i++) {
        pos = 0;
        db tmpl = -1E9, tmpr = -1E9, tl, tr;
        for (int j = 1; j <= n; j++)
            if (cut[i] >= a[j] - c[j] / 2.0 && cut[i + 1] <= a[j]) {
                tl = (cut[i] - a[j] + c[j] / 2.0) / (c[j] / 2.0) * b[j];
                tr = (cut[i + 1] - a[j] + c[j] / 2.0) / (c[j] / 2.0) * b[j];
                if (tl + tr >
                    tmpl +
                        tmpr)  //就是這個地方!不要寫tl>tmpl||tr>tmpr,因爲浮點誤差的原因,有可能實際相同的點,反而低山峯的那個點更高那麼一小丟丟,造成pos指向了低山峯。
                    tmpl = tl, tmpr = tr, pos = j;
            } else if (cut[i] >= a[j] && cut[i + 1] <= a[j] + c[j] / 2.0) {
                tl = b[j] - (cut[i] - a[j]) / (c[j] / 2.0) * b[j];
                tr = b[j] - (cut[i + 1] - a[j]) / (c[j] / 2.0) * b[j];
                if (tl + tr > tmpl + tmpr) tmpl = tl, tmpr = tr, pos = j;
            }
        if (pos)
            ans += (cut[i + 1] - cut[i]) *
                   sqrtl(1 +
                         (b[pos] / (c[pos] / 2.0)) * (b[pos] / (c[pos] / 2.0)));
    }
    printf("%d", (int)(ans + 0.5));
    return 0;
}

java:

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner read = new Scanner(System.in);
		int N = read.nextInt();
		double num[][] = new double[N][3];
		List<Mon> liss = new ArrayList<Mon>();
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < 3; j++)
				num[i][j] = read.nextDouble();
		}
		Line l[] = new Line[N];
		List<Node> list = new ArrayList<Node>();
		for (int i = 0; i < N; i++) {
			Line li = new Line();
			double x1 = num[i][0] - num[i][2] / 2;
			double x2 = num[i][0];
			double y2 = num[i][1];
			double x3 = num[i][0] + num[i][2] / 2;
			li.k1 = (y2 / (x2 - x1));		
			li.b1 = x1 * y2 / (x1 - x2);
			li.k2 = (y2 / (x2 - x3));
			li.b2 = x3 * y2 / (x3 - x2);
			l[i] = li;
			list.add(new Node(x1, 0));
			list.add(new Node(x2, y2));
			list.add(new Node(x3, 0));
			liss.add(new Mon(x2, y2, li));
		}
		Collections.sort(liss);
		for (int i = 0; i < N - 1; i++) {
			Mon n1 = liss.get(i);
			for (int j = i + 1; j < N; j++) {
				Mon n2 = liss.get(j);
				Line l1 = n1.l;
				Line l2 = n2.l;
				try {
					l1.x = (l2.b1 - l1.b1) / (l1.k1 - l2.k1);
					l1.y = l1.k1 * l1.x + l1.b1;
					if (l1.y >= 0 && l1.y <= n1.y && l1.y <= n2.y) {
						list.add(new Node(l1.x, l1.y));
					}
				} catch (Exception e) {
				}
				try {
					l1.x = (l2.b1 - l1.b2) / (l1.k2 - l2.k1);
					l1.y2 = l1.k2 * l1.x + l1.b2;
					if (l1.y2 >= 0 && l1.y2 <= n1.y && l1.y2 <= n2.y) {
						list.add(new Node(l1.x, l1.y2));
					}
				} catch (Exception e) {
				}
				try {
					l1.x = (l2.b2 - l1.b2) / (l1.k2 - l2.k2);
					l1.y2 = l1.k2 * l1.x + l1.b2;
					if (l1.y2 >= 0 && l1.y2 <= n1.y && l1.y2 <= n2.y) {
						list.add(new Node(l1.x, l1.y2));
					}
				} catch (Exception e) {
				}
			}
		}
		Collections.sort(list);
		for (int i = 0; i < list.size(); i++) {
			Node n = list.get(i);
		}
		double sum = 0;
		for (int i = 0; i < list.size() - 1; i++) {		
			Node n1 = list.get(i);
			Node n2 = list.get(i + 1);
			double x = (n2.x - n1.x) / 2 + n1.x;
			int ind = 0;
			int ind2 = 0;
			double max = 0;
			for (int j = 0; j < liss.size(); j++) {
				Mon m = liss.get(j);
				m.l.x = x;
				if (n2.x <= m.x) {
					m.l.y = m.l.k1 * m.l.x + m.l.b1;
					if (m.l.y > max) {
						ind = j;
						ind2 = 0;
						max = m.l.y;
					}
				} else {
					m.l.y2 = m.l.k2 * m.l.x + m.l.b2;
					if (m.l.y2 > max) {
						ind = j;
						ind2 = 1;
						max = m.l.y2;
					}
				}
			}
			Mon m = liss.get(ind);
			if (max == 0)
				continue;
			double y1 = 0, y2 = 0;
			if (ind2 == 0) {
				m.l.x = n1.x;
				m.l.y = m.l.k1 * m.l.x + m.l.b1;
				y1 = m.l.y;
				m.l.x = n2.x;
				m.l.y = m.l.k1 * m.l.x + m.l.b1;
				y2 = m.l.y;
				sum += Math.sqrt(Math.pow(n2.x - n1.x, 2) + Math.pow(y1 - y2, 2));
			} else {
				m.l.x = n1.x;
				m.l.y2 = m.l.k2 * m.l.x + m.l.b2;
				y1 = m.l.y2;
				m.l.x = n2.x;
				m.l.y2 = m.l.k2 * m.l.x + m.l.b2;
				y2 = m.l.y2;
				sum += Math.sqrt(Math.pow(n2.x - n1.x, 2) + Math.pow(y1 - y2, 2));
			}
		}
		System.out.println(String.format("%.0f", sum));
	}
}
class Mon implements Comparable<Mon> {
	Line l;
	double x;
	double y;
	public Mon(double x, double y, Line l) {
		super();
		this.x = x;
		this.y = y;
		this.l = l;
	}
	@Override
	public int compareTo(Mon o) {
		// TODO Auto-generated method stub
		return (int) (this.x - o.x);
	}
}
class Line {
	double x;
	double k1, b1, k2, b2;
	double y;
	double y2;
}
class Node implements Comparable<Node> {
	double x;
	double y;

	public Node(double x, double y) {
		super();
		this.x = x;
		this.y = y;
	}
	@Override
	public int compareTo(Node o) {
		// TODO Auto-generated method stub
		return (int) (this.x * 1000 - o.x * 1000);
	}
}

ADV-264 Degrees of Separation

cpp:

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const int MAXN = 50 + 1;
vector<int> graph[MAXN];  //鄰接表
int P, R;
bool vis[MAXN];  //記錄結點是否訪問
int dis[MAXN];   //到達結點的步數
map<string, int> People;
int ans = 0;

void Bfs(int u) {  //標準的Bfs格式,因本題求最大分離度,略微複雜
    memset(dis, 0, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    queue<int> Q;
    vis[u] = 1;
    Q.push(u);
    int num = 1;  //記錄訪問的結點個數

    while (!Q.empty()) {
        int now = Q.front();

        if (num == P &&
            Q.size() == 1)  //判斷結點是否都訪問過了,並且是最後一個結點
            ans = max(ans, dis[now]);

        Q.pop();

        for (int i = 0; i < graph[now].size(); i++) {
            int next = graph[now][i];
            if (!vis[next]) {
                vis[next] = 1;
                dis[next] = dis[now] + 1;  //步數加1
                num++;                     //已訪問的結點加1
                Q.push(next);
            }
        }
    }
}

int main() {
    int ccase = 0;

    while (scanf("%d%d", &P, &R) && P && R) {
        People.clear();
        for (int i = 0; i < MAXN; i++) graph[i].clear();
        ccase++;
        ans = 0;

        int k = 1;
        char c[20], d[20];
        // string c, d;
        for (int i = 0; i < R; i++) {
            // cin >> c >> d;
            scanf("%s%s", c, d);
            if (!People[c])  //將string映射到int
                People[c] = k++;
            if (!People[d]) People[d] = k++;
            graph[People[c]].push_back(People[d]);
            graph[People[d]].push_back(People[c]);
        }

        for (int i = 1; i <= P; i++) {
            Bfs(i);
        }
        if (ans == 0)
            printf("Network %d: DISCONNECTED\n\n", ccase);
        else
            printf("Network %d: %d\n\n", ccase, ans);
    }
    return 0;
}

java:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.StringTokenizer;
class R{
	static BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokenizer=new StringTokenizer("");
	static String nextLine() throws IOException {
		return reader.readLine();
	}
	static String next() throws IOException {
		while(!tokenizer.hasMoreTokens()) {
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	static int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(next());
	}
	static Double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(next());
	}
}
public class Main {
	//static Scanner cin=new Scanner(System.in);
	static int p,r;
	static String s[]=new String[300];
	static int len[][]=new int[55][55];
	static String q;
	static Map mp=new HashMap<String, Integer>();
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		int cas=1;
		while(true) {
			p=R.nextInt();
			r=R.nextInt();
			if(p==0&&r==0) break;
			mp.clear();
			int cnt=1;
			for(int i=1;i<=p;i++) {
				for(int j=1;j<=p;j++) {
					len[i][j]=1000000000;
				}
				len[i][i]=0;
			}
			for(int i=0;i<r;i++) {
				String a,b;
				a=R.next();
				b=R.next();
				if(mp.containsKey(a)==false) {
					mp.put(a, cnt);
					cnt++;
				}
				if(mp.containsKey(b)==false) {
					mp.put(b, cnt);
					cnt++;
				}
				len[(int) mp.get(a)][(int) mp.get(b)]=1;
				len[(int) mp.get(b)][(int) mp.get(a)]=1;
			}
			int ans=0;
			for(int i=1;i<=p;i++) {
				for(int j=1;j<=p;j++) {
					for(int k=1;k<=p;k++) {
						len[j][k]=Math.min(len[j][k],len[j][i]+len[i][k]);
					}
				}
			}
			for(int i=1;i<=p;i++) {
				for(int j=1;j<=p;j++) {
					ans=Math.max(ans, len[i][j]);
				}
			}
			if(ans==1000000000) System.out.println("Network "+cas+": DISCONNECTED");
			else System.out.println("Network "+cas+": "+ans);
			System.out.println();
			cas++;
		}
	}
}

ADV-265 Cutting Chains

cpp:

#include <algorithm>
#include <cstring>
#include <iostream>
#define ms(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 20 + 5;

int G[maxn][maxn], vis[maxn], n, maxd, open[maxn], cnt = 0;

bool dfs2(int p, int r) {
    for (int i = 1; i <= n; i++) {
        if (i == p || i == r) continue;
        if (G[p][i] && !open[i]) {
            if (!vis[i]) {
                vis[i] = 1;
                if (dfs2(i, p)) return true;
            } else
                return true;
        }
    }
    return false;
}

bool check() {
    for (int i = 1; i <= n; i++) {
        if (open[i]) continue;
        int s = 0;
        for (int j = 1; j <= n; j++) {
            if (G[i][j] && !open[j]) s++;
        }
        if (s > 2) return false;
    }
    ms(vis, 0);
    cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (!open[i] && !vis[i]) {
            vis[i] = 1;
            if (dfs2(i, i)) return false;
            cnt++;
        }
    }
    return maxd >= cnt - 1;
}

bool dfs(int p, int d) {
    if (d == maxd) {
        return check();
    }
    if (p > n) return false;

    open[p] = 1;
    if (dfs(p + 1, d + 1)) return true;
    open[p] = 0;
    if (dfs(p + 1, d)) return true;

    return false;
}

int main() {
    int kase = 0;
    while (cin >> n && n) {
        int x, y;
        ms(G, 0);
        while (cin >> x >> y) {
            if (x == -1 && y == -1) break;
            G[x][y] = G[y][x] = 1;
        }
        int flag = 0;
        for (maxd = 0; !flag; maxd++) {
            ms(open, 0);
            flag = dfs(1, 0);
        }
        cout << "Set " << ++kase << ": Minimum links to open is ";
        cout << maxd - 1 << endl;
    }
    return 0;
}

java:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static int INF =0x3f3f3f3f;
	 static int vis[] = new int[20];
	static int g[][] = new int[20][20];
	static int n,  cn;
	static StreamTokenizer in;
	static void init() throws IOException {
		int a = 0, b = 0;
		g = new int[20][20];
		

		while (true) {
			in.nextToken();
			a=(int) in.nval;
			in.nextToken();
			b=(int) in.nval;
			if( a == -1 && b == -1)
				break;
			g[a - 1][b - 1] = g[b - 1][a - 1] = 1;
		}
	}
	 
	static boolean two(int s) {
		for (int i = 0; i < n; i++) {
			if ((s&(1<<i))!=0) continue;
			int num = 0;
			for (int j = 0; j < n; j++) {
				if ((s&(1<<j))!=0) continue;
				if (g[i][j]!=0) num++;
			}
			if (num > 2) return true;
		}	
		return false;
	}
	 
	static boolean dfs(int s, int now, int fa) {
		vis[now] = 1;
		for (int i = 0; i < n; i++) {
			if (!(g[now][i]!=0) || (s&(1<<i))!=0 || i == fa) continue;
			if (vis[i]!=0) return true;
			if (dfs(s, i, now)) return true;
		}
		return false;
	}
	 
	static boolean circle(int s) {
		for (int i = 0; i < n; i++) {
			if (vis[i]!=0|| (s&(1<<i))!=0) continue;
			cn++;
			if (dfs(s, i, -1)) return true;
		}
		return false;
	}
	 
	static int cal(int s) {
		return s == 0 ? 0 : cal(s / 2) + (s&1);
	}
	 
	static int solve() {
		int ans = INF;
		int s = (1<<n);
		for (int i = 0; i < s; i++) {
			cn = 0; 
			vis = new int[20];
			if(two(i) || circle(i)) continue;
			if (cal(i) >= cn - 1)
				ans = Math.min(cal(i), ans);
		}
		return ans;
	}
	public static void main(String[] args) throws IOException {
		in= new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		int cas = 0;

		while (true) {
			in.nextToken();
			n=(int) in.nval;
			if(n==0)
				break;
			init();
			System.out.println("Set "+ ++cas+": Minimum links to open is "+solve());
		}

	}

}

ADV-270 Flight Planning

cpp:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
using namespace std;
const int maxn = 1000 + 10;
long long dp[maxn][maxn];
int ans[maxn], s[maxn];
int he[maxn][maxn];
int main() {
    int x;
    scanf("%d", &x);
    int u = 1;
    while (x--) {
        int a, b, c, n;
        scanf("%d", &n);
        scanf("%d %d %d", &a, &b, &c);
        for (int i = 20; i <= 40; i++) {
            double w = (c - b) * (i - 20) * 1.0 / 20.0 + b;
            double v = 400 + w;
            double t = a / (1.0 * v);
            dp[1][i] = ((fabs(i - 30) * 10 + 2000) * t + i * 50) * 10000;
        }
        for (int i = 2; i <= n; i++) {
            scanf("%d %d %d", &a, &b, &c);
            for (int j = 20; j <= 40; j++) {
                dp[i][j] = LONG_LONG_MAX;
                double w = (c - b) * (j - 20) * 1.0 / 20.0 + b;
                double v = 400 + w;
                double t = a / (1.0 * v);
                for (int k = 20; k <= 40; k++) {
                    long long o =
                        dp[i - 1][k] + (fabs(j - 30) * 10 + 2000) * t * 10000;
                    if (j > k) o += (j - k) * 500000;
                    if (dp[i][j] > o) {
                        he[i][j] = k;
                        dp[i][j] = o;
                    }
                }
            }
        }
        for (int i = 1; i <= n; i++) ans[i] = INT_MAX;
        long long mi = LONG_LONG_MAX;
        for (int i = 20; i <= 40; i++) {
            mi = min(mi, dp[n][i]);
        }
        for (int i = 20; i <= 40; i++) {
            if (dp[n][i] == mi) {
                int p = n, c = i;
                while (he[p][c]) {
                    s[p] = c;
                    c = he[p][c];
                    p--;
                }
                s[p] = c;
                int flag = 0;
                for (int j = 1; j <= n; j++) {
                    if (s[j] < ans[j]) {
                        flag++;
                        break;
                    }
                    if (s[j] > ans[j]) {
                        break;
                    }
                }
                if (flag) {
                    for (int j = 1; j <= n; j++) {
                        ans[j] = s[j];
                    }
                }
            }
        }
        printf("Flight %d: ", u++);
        for (int i = 1; i <= n; i++) {
            printf("%d ", ans[i]);
        }
        printf("%lld\n", mi / 10000 + 1);
    }
    return 0;
}

java:

import java.util.*;
public class Main {
	static Scanner sc=new Scanner(System.in);
	static int V=400;
	static int GP=2000,GE=10,C=50;
	static int A=30;	
	
	static double dp[][];
	static int m[][];		//記憶前一段的高度
	static int Arr[][];	//A[i][0]記錄最低點風速 A[i][1]記錄最高點風速
	static int H[];			//長度數組
	static int K;			//個數
	
	static void init() {		//沒問題
		K=sc.nextInt();
		H=new int[K+1];
		dp=new double[K+1][21];
		m=new int[K+1][21];
		Arr=new int[K+1][2];
		for(int i=1;i<=K;i++) {
			H[i]=sc.nextInt();
			Arr[i][0]=sc.nextInt();
			Arr[i][1]=sc.nextInt();
		}
		for(int j=0;j<=20;j++) {
			dp[0][j]=C*(j+20);
		}
	}
	
	public static void main(String[] args) {
		int n=sc.nextInt();
		for(int i=1;i<=n;i++) {
			init();
			for(int k=1;k<=K;k++)
				for(int j=0;j<=20;j++)
					getDP(k,j);
			double min=1000000000;
			int p=-1;
			for(int j=0;j<=20;j++) {
				if(dp[K][j]<min) {
					min=dp[K][j];
					p=j;
				}
			}
			print(p,i);
			System.out.println((int)Math.ceil(min));
		}
	}
	static void print(int k,int j) {
		int arr[]=new int[K];
		int p=k;
		for(int i=K;i>=1;i--) {
			arr[i-1]=k=m[i][k];
		}
		System.out.print("Flight "+j+": ");
		for(int i=1;i<K;i++) {
			System.out.print(arr[i]+20+" ");
		}
		System.out.print((p+20)+" ");
	}
	static void getDP(int i,int j) {	//
		double min=100000000;
		for(int k=0;k<=20;k++) {
			double num=dp[i-1][k];
			if(k<j)
				num+=50*(j-k);
			if(min>num) {
				m[i][j]=k;
				min=num;
			}
		}
		min+=getHY(i,j);
		dp[i][j]=min;
		//System.out.println(i+" "+j+" "+dp[i][j]);
	}
	
	static double getHY(int i,int h) {	//第i段航線高度爲h的耗油數 沒問題
		//System.out.println("第"+i+"段,風速爲:"+(V+getV(i,h))+" 高度爲:"+h+"  耗油數爲:"+getY(h)+" 總耗油爲:"+(H[i]*getY(h)/(V+getV(i,h))));
		return H[i]*getY(h)/(V+getV(i,h));
	}
	static double getY(int h) {
		return 2000+Math.abs(10-h)*10;
	}
	static double getV(int i,int x) {		//得到第i段航路高度爲x的風速
		return (double)(Arr[i][1]-Arr[i][0])*x/20+Arr[i][0];
	}
}

ADV-271 Stacking Plates

cpp:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#include <vector>

using namespace std;

const int INF = 0x3f3f3f3f;

int kase, n, id[10005], vis[55][2505], dp[2505][55];
// id[i]爲盤子直徑i離散化後的值, vis[i][j]判斷堆i中是否出現過第j種盤子,
// dp[i][j]表示把前i種盤子排好放到堆j的最小花費
vector<int> plates[55];  //輸入數據
set<int> val;            //用於離散化
vector<int> heap[2505];  // heap[i]表示第i種盤子對應的堆

// 初始化全局變量
void init() {
    memset(dp, INF, sizeof(dp));
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) plates[i].clear();
    val.clear();
    for (int i = 1; i <= 2500; i++) heap[i].clear();
}

// 離散化並返回不同直徑盤子的種類
int discrete() {
    int ran = 0;
    for (set<int>::iterator it = val.begin(); it != val.end(); it++)
        id[*it] = ++ran;
    return ran;
}

int main() {
    while (~scanf("%d", &n)) {
        init();

        // 處理輸入數據
        int k, x;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &k);
            while (k--) {
                scanf("%d", &x);
                plates[i].push_back(x);
                val.insert(x);
            }
        }

        // 離散化以及算出每個類型盤子所在的堆id
        int ran = discrete();
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < plates[i].size(); j++) {
                x = id[plates[i][j]];
                if (!vis[i][x]) {
                    vis[i][x] = 1;
                    heap[x].push_back(i);  //保證第x種盤子對應的堆不重複
                }
            }
        }

        // 動態規劃算出最優值
        for (int i = 0; i < heap[1].size(); i++)
            dp[1][heap[1][i]] = heap[1].size() - 1;
        for (int i = 2; i <= ran; i++) {
            for (int a = 0; a < heap[i].size(); a++) {
                for (int b = 0; b < heap[i - 1].size(); b++) {
                    int j = heap[i][a], k = heap[i - 1][b],
                        cnt = heap[i].size();
                    if (j == k)
                        dp[i][j] = min(
                            dp[i][j],
                            dp[i - 1][j] +
                                (cnt == 1 ? 0 : cnt));  // cnt-1==0?0:cnt-1+1
                    else
                        dp[i][j] =
                            min(dp[i][j], dp[i - 1][k] + cnt - 1 + !vis[k][i]);
                }
            }
        }

        // 處理及輸出結果
        int ans = INF;
        for (int i = 0; i < heap[ran].size(); i++)
            ans = min(ans, dp[ran][heap[ran][i]]);
        printf("Case %d: %d\n", ++kase, 2 * ans - n + 1);
    }
    return 0;
}

ADV-275 JOE的算數

cpp:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-5;
inline int read() {
    int f = 1, x = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return f * x;
}
ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
ll poww(ll x, ll y, ll p) {
    ll ans = 1;
    while (y) {
        if (y & 1) ans = ans * x % p;
        x = x * x % p;
        y >>= 1;
    }
    return ans;
}
ll a, b, c;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);  // open-> can't use scanf,printf!!
    cin >> a >> b >> c;
    cout << poww(a, b, c) << endl;
    return 0;
}

java:


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long a=sc.nextLong();
		int b=sc.nextInt();
		int c=sc.nextInt();
		long res=1;
		while (b!=0) {
			if ((b&1)==1) {
				res=(res*a)%c;
			}
			a=(a*a)%c;
			b>>=1;
		}
		System.out.println(res);
	}
}

ADV-276 Raising the Roof

暫時未通過

ADV-277 The Islands

cpp:


#include <bits/stdc++.h>
using namespace std;
const int maxn = 104;
struct point {
    int x, y;
    point() {}
    point(int xx, int yy) {
        this->x = xx;
        this->y = yy;
    }
} a[maxn], pre[maxn][maxn];

int inline p2(int x) { return x * x; }
inline double dis(point a, point b) {
    return sqrt(p2(a.x - b.x) + p2(a.y - b.y));
}

int n, m1, m2;
double dp[maxn][maxn];
bool vis[maxn][maxn];
int main() {
    int cas = 1;
    while (scanf("%d%d%d", &n, &m1, &m2) != EOF) {
        if (n == 0 && m1 == 0 && m2 == 0) {
            break;
        }
        m1++, m2++;
        for (int i = 1; i <= n; i++) {
            scanf("%d%d", &a[i].x, &a[i].y);
        }
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                vis[i][j] = false;
                dp[i][j] = 1e10;
            }
        }
        dp[1][1] = 0;
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                if (i != 1 && i == j) continue;
                if (i >= j) {  // i+1的去哪
                    // dp[i][j] -> dp[i+1][j] = dp[i][j]+dis(i,i+1)  dp[i][i+1]
                    // = dp[i][j]+dis(j,i+1)
                    if (i + 1 != m2 &&
                        (vis[i + 1][j] == false ||
                         dp[i + 1][j] > dp[i][j] + dis(a[i], a[i + 1]))) {
                        pre[i + 1][j] = point(i, j);
                        vis[i + 1][j] = true;
                        dp[i + 1][j] = dp[i][j] + dis(a[i], a[i + 1]);
                        // printf("%d %d -> %d %d (1)\n",i,j,i+1,j);
                    }
                    if (i + 1 != m1 &&
                        (vis[i][i + 1] == false ||
                         dp[i][i + 1] > dp[i][j] + dis(a[j], a[i + 1]))) {
                        pre[i][i + 1] = point(i, j);
                        vis[i][i + 1] = true;
                        dp[i][i + 1] = dp[i][j] + dis(a[j], a[i + 1]);
                        // printf("%d %d -> %d %d (2)\n",i,j,i,i+1);
                    }
                }
                if (i <= j) {  // j+1的去哪
                    // dp[i][j] -> dp[i][j+1] = dp[i][j]+dis(j,j+1)  dp[j+1][j]
                    // = dp[i][j]+dis(i,j+1)
                    if (j + 1 != m1 &&
                        (vis[i][j + 1] == false ||
                         dp[i][j + 1] > dp[i][j] + dis(a[j], a[j + 1]))) {
                        pre[i][j + 1] = point(i, j);
                        vis[i][j + 1] = true;
                        dp[i][j + 1] = dp[i][j] + dis(a[j], a[j + 1]);
                        // printf("%d %d -> %d %d (3)\n",i,j,i,j+1);
                    }
                    if (j + 1 != m2 &&
                        (vis[j + 1][j] == false ||
                         dp[j + 1][j] > dp[i][j] + dis(a[i], a[j + 1]))) {
                        pre[j + 1][j] = point(i, j);
                        vis[j + 1][j] = true;
                        dp[j + 1][j] = dp[i][j] + dis(a[i], a[j + 1]);
                        // printf("%d %d -> %d %d (4)\n",i,j,j+1,j);
                    }
                }
            }
        }
        /*for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                printf("dp[%d][%d] = %15.2f  ",i,j,dp[i][j]);
            }
            printf("\n");
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                printf("pre[%d][%d] = (%d, %d)  ",i,j,pre[i][j].x, pre[i][j].y);
            }
            printf("\n");
        }*/
        double ans = 1e20;
        int posx = -1, posy = n;
        for (int i = 1; i <= n; i++) {
            if (i == m2) continue;
            if (ans > dp[i][n] + dis(a[i], a[n])) {
                ans = dp[i][n] + dis(a[i], a[n]);
                posx = i;
            }
        }
        vector<int> way1, way2;
        while (posx != 0 && posy != 0) {
            // printf("%d %d ->",posx,posy);
            if (pre[posx][posy].x != posx) {
                way1.push_back(posx);
                posx = pre[posx][posy].x;
            } else {
                way2.push_back(posy);
                posy = pre[posx][posy].y;
            }
        }
        vector<int> xcx;
        printf("Case %d: %.2f\n", cas++, ans);
        for (int i = way1.size() - 1; i >= 0; i--) {
            xcx.push_back(way1[i] - 1);
        }
        for (int i = 0; i < way2.size(); i++) {
            xcx.push_back(way2[i] - 1);
        }
        xcx.push_back(0);
        if (xcx[1] != 1) {
            reverse(xcx.begin(), xcx.end());
        }
        for (int i = 0; i < xcx.size(); i++) {
            if (i != 0) {
                printf(" ");
            }
            printf("%d", xcx[i]);
        }
        printf("\n");
    }
    return 0;
}

ADV-278 歌唱比賽

cpp:

#include <stdio.h>
int main() {
    int n;
    scanf("%d", &n);
    while (n--) {
        double sum = 0;
        int a, b, c, d;
        scanf("%d%d%d%d", &a, &b, &c, &d);
        sum += a * 0.7 + b * 0.2 + c * 0.1 + d;
        sum = sum > 100 ? 100 : sum;
        printf("%0.1f\n", sum);
    }
}

java:

import java.text.DecimalFormat;
import java.util.*;
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner reader = new Scanner(System.in);
		DecimalFormat df = new DecimalFormat("#.0");
		int n;
		n = reader.nextInt();
		int a,b,c,d;
		double[] sum = new double[n];
		for(int i=0;i<n;i++){
			a = reader.nextInt();
			b = reader.nextInt();
			c = reader.nextInt();
			d = reader.nextInt();
			sum[i] = 0.7*a+0.2*b+0.1*c+d;
			if(sum[i] > 100)
				sum[i] = 100;	
		}
		for(int i=0;i<n;i++)
			System.out.print(df.format(sum[i])+"\n");
			//System.out.print(String.format("%.1f", sum));	
	}

}

ADV-279 矩陣乘法

cpp:

#include <stdio.h>
int main() {
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    int a[n + 1][m + 1], b[m + 1][k + 1];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]);
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= k; j++) scanf("%d", &b[i][j]);
    int c[n + 1][k + 1];
    int x = 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++) {
            x = 1;
            c[i][j] = 0;
            while (x <= m) {
                c[i][j] += a[i][x] * b[x][j];
                x++;
            }
        }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= k; j++) printf("%d ", c[i][j]);
        printf("\n");
    }
    return 0;
}

java:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int mar1[][] = new int[n][m];
		int mar2[][] = new int[m][k];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				mar1[i][j] = sc.nextInt();
			}
		}
		for(int i=0;i<m;i++) {
			for(int j=0;j<k;j++) {
				mar2[i][j] = sc.nextInt();
			}
		}
		
		int ans[][] = new int[n][k];
		for(int i=0;i<n;i++) {
			for(int j=0;j<k;j++) {
				for(int t=0;t<m;t++) {
					ans[i][j] += mar1[i][t]*mar2[t][j];
				}
				System.out.print(ans[i][j]+" ");
			}
			System.out.println();
		}
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章