zoukankan      html  css  js  c++  java
  • 2020ICPC小米 网络选拔赛第一场部分题解

    比赛链接:2020ICPC小米 网络选拔赛第一场



    A - Intelligent Warehouse

    题目要求选择一串连续的数列,使每一个都是上一个的倍数,由于一个数可以存在很多因数,所以选择用动态规划来做。状态转移方程:

    [dp[j] = max(dp[i]) + cnt[j],j \% i = 0 ]

    #include <iostream>
    using namespace std;
    #define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define N 10000000 + 10
    
    int n, tmp, dp[N], cnt[N], ans;
    
    int main() {
    	io_speed_up;
    	cin >> n;
    	for (int i = 1; i <= n; ++i) {
    		cin >> tmp;
    		cnt[tmp]++;
    	}
    	for (int i = 1; i <= 10000000; ++i) {
    		if (!cnt[i]) {
    			continue;
    		}
    		dp[i] += cnt[i];
    		ans = max(ans, dp[i]);
    		for (int j = i * 2; j <= 10000000; j += i) {
    			dp[j] = max(dp[j], dp[i]);
    		}
    	}
    	cout << ans;
    	return 0;
    }
    

    B - Intelligent Robot

    假设有一堵墙挡在必经之路上,那最短路径一定是从起点径直走向墙的端点再径直走向终点。
    所以可以将题目看成是(k)堵墙(2 * k)的端点加上起点和终点共(2 * k + 2)个端点跑最短路。
    接下来考虑建边:
    如果两点之间的线段与所有墙都没有交点或者交点是墙的两个端点,则这条线段可以建边。
    至于判断线段相交,较常见的就是叉乘。这里贴一个大佬的博客

    #include <iostream>
    #include <cmath>
    #include <queue>
    #include <iomanip>
    using namespace std;
    #define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define INF 0x3f3f3f3f
    #define N 610
    
    int n, m, k;
    int head[N], cnt;
    double dis[N];
    
    struct Point {
    	int x, y;
    	Point operator - (const Point &p) const {
    		return Point{x - p.x, y - p.y};
    	}
    } wall[N];
    
    struct Node {
    	int u;
    	double dis;
    	bool operator < (const Node &x) const {
    		return dis < x.dis;
    	}
    };
    
    struct Edge {
    	int v, next;
    	double dis;
    } edge[N * N];
    
    void addEdge(int u, int v, double dis) {
    	edge[++cnt].v = v;
    	edge[cnt].dis = dis;
    	edge[cnt].next = head[u];
    	head[u] = cnt;
    }
    
    int mul(Point p, Point q) {
    	int tmp = p.x * q.y - p.y * q.x;
    	return tmp < 0 ? -1 : tmp > 0;
    }
    
    bool judge(Point p1, Point p2, Point q1, Point q2) {
    	int t1 = mul(p2 - p1, q1 - p1);
    	int t2 = mul(p2 - p1, q2 - p1);
    	int t3 = mul(q2 - q1, p1 - q1);
    	int t4 = mul(q2 - q1, p2 - q1);
    	return t1 * t2 < 0 && t3 * t4 < 0;
    }
    
    bool check(Point p, Point q) {
    	for (int i = 1; i <= k; ++i) {
    		if (judge(p, q, wall[2 * i - 1], wall[2 * i])) {
    			return false;
    		}
    	}
    	return true;
    }
    
    double getDis(Point p, Point q) {
    	return sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y));
    }
    
    void dijkstra() {
    	for (int i = 1; i <= 2 * k + 2; ++i) {
    		dis[i] = INF;
    	}
    	priority_queue <Node> q;
    	q.push(Node{2 * k + 1, 0});
    	dis[2 * k + 1] = 0;
    	while (!q.empty()) {
    		int u = q.top().u;
    		double d = q.top().dis;
    		q.pop();
    		if (d > dis[u]) {
    			continue;
    		}
    		for (int i = head[u]; i; i = edge[i].next) {
    			if (dis[edge[i].v] > dis[u] + edge[i].dis) {
    				dis[edge[i].v] = dis[u] + edge[i].dis;
    				q.push(Node{edge[i].v, dis[edge[i].v]});
    			}
    		}
    	}
    }
    
    int main() {
    	io_speed_up;
    	cin >> n >> m >> k;
    	for (int i = 1; i <= k; ++i) {
    		cin >> wall[i * 2 - 1].x >> wall[i * 2 - 1].y;
    		cin >> wall[i * 2].x >> wall[i * 2].y;
    	}
    	cin >> wall[2 * k + 1].x >> wall[2 * k + 1].y;
    	cin >> wall[2 * k + 2].x >> wall[2 * k + 2].y;
    	for (int i = 1; i <= 2 * k + 2; ++i) {
    		for (int j = i + 1; j <= 2 * k + 2; ++j) {
    			if (check(wall[i], wall[j])) {
    				double len = getDis(wall[i], wall[j]);
    				addEdge(i, j, len);
    				addEdge(j, i, len);
    			}
    		}
    	}
    	dijkstra();
    	cout << fixed << setprecision(4);
    	cout << dis[2 * k + 2];
    	return 0;
    }
    

    C - Smart Browser

    按顺序对w计数,(1)个w有(1)个/,(n)个w有(2 imes n-1)个/。

    #include <iostream>
    #include <string>
    using namespace std;
    #define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    
    int cnt, len, ans;
    
    int main() {
    	string s;
    	cin >> s;
    	len = s.length();
    	for (int i = 0; i < len; ++i) {
    		if (s[i] == 'w') {
    			cnt++;
    		} else {
    			if (cnt == 1) {
    				ans += 1;
    			} else if (cnt > 1) {
    				ans += 2 * cnt - 1;
    			}
    			cnt = 0;
    		}
    	}
    	if (cnt == 1) {
    		ans += 1;
    	} else if (cnt > 1) {
    		ans += 2 * cnt - 1;
    	}
    	cout << ans;
    	return 0;
    }
    

    I - Walking Machine

    对最外面一圈能出去的位置往里进行搜索,标识方向和搜索方向相反则代表可以走出来。

    #include <iostream>
    using namespace std;
    #define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define N 1000 + 10
    
    const int mod = 1e9 + 7;
    char mat[N][N];
    int n, m, ans;
    bool vis[N][N];
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    
    void dfs(int x, int y) {
    	ans++;
    	for (int i = 0; i < 4; ++i) {
    		int nxtx = x + dx[i], nxty = y + dy[i];
    		if (nxtx >= 1 && nxtx <= n && nxty >= 1 && nxty <= m && !vis[nxtx][nxty]) {
    			if (i == 0 && mat[nxtx][nxty] == 'W') {
    				vis[nxtx][nxty] = true;
    				dfs(nxtx, nxty);
    			}
    			if (i == 1 && mat[nxtx][nxty] == 'S') {
    				vis[nxtx][nxty] = true;
    				dfs(nxtx, nxty);
    			}
    			if (i == 2 && mat[nxtx][nxty] == 'A') {
    				vis[nxtx][nxty] = true;
    				dfs(nxtx, nxty);
    			}
    			if (i == 3 && mat[nxtx][nxty] == 'D') {
    				vis[nxtx][nxty] = true;
    				dfs(nxtx, nxty);
    			}
    		}
    	}
    }
    
    int main() {
    	io_speed_up;
    	cin >> n >> m;
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= m; ++j) {
    			cin >> mat[i][j];
    		}
    	}
    	if (!vis[1][1] && (mat[1][1] == 'A' || mat[1][1] == 'W')) {
    		vis[1][1] = true;
    		dfs(1, 1);
    	}
    	if (!vis[1][m] && (mat[1][m] == 'D' || mat[1][m] == 'W')) {
    		vis[1][m] = true;
    		dfs(1, m);
    	}
    	if (!vis[n][1] && (mat[n][1] == 'A' || mat[n][1] == 'S')) {
    		vis[n][1] = true;
    		dfs(n, 1);
    	}
    	if (!vis[n][m] && (mat[n][m] == 'D' || mat[n][m] == 'S')) {
    		vis[n][m] = true;
    		dfs(n, m);
    	}
    	for (int i = 2; i <= m - 1; ++i) {
    		if (!vis[1][i] && mat[1][i] == 'W') {
    			vis[1][i] = true;
    			dfs(1, i);
    		}
    		if (!vis[n][i] && mat[n][i] == 'S') {
    			vis[n][i] = true;
    			dfs(n, i);
    		}
    	}
    	for (int i = 2; i <= n - 1; ++i) {
    		if (!vis[i][1] && mat[i][1] == 'A') {
    			vis[i][1] = true;
    			dfs(i, 1);
    		}
    		if (!vis[i][m] && mat[i][m] == 'D') {
    			vis[i][m] = true;
    			dfs(i, m);
    		}
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    Java8 Stream Function
    PLINQ (C#/.Net 4.5.1) vs Stream (JDK/Java 8) Performance
    罗素 尊重 《事实》
    小品 《研发的一天》
    Java8 λ表达式 stream group by max then Option then PlainObject
    这人好像一条狗啊。什么是共识?
    TOGAF TheOpenGroup引领开发厂商中立的开放技术标准和认证
    OpenMP vs. MPI
    BPMN2 online draw tools 在线作图工具
    DecisionCamp 2019, Decision Manager, AI, and the Future
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/13875273.html
Copyright © 2011-2022 走看看