A.爆炸题 图论,最短路,思维
给出一个图,从1点开始每秒为1米的速度火焰扩展,如果遇到大于一个火焰相遇就会爆炸,问最终爆炸的个数
容易得出以下规律:如果在某个点爆炸,那么这个点存在大于1的入度使得最短路相等 如果在边上爆炸,那么这条边不在最短路上
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> #define INF 0x3f3f3f3f const int maxn = 300000 + 10; const double PI = acos(-1.0); typedef long long ll; using namespace std; int n, m; struct edge { int v, w; edge(int a, int b) { v = a, w = b; } };//v终点,w边权 struct node { int id, dis;//id点编号 dis暂时距离 node(int a, int b) { id = a, dis = b; } friend bool operator<(node a, node b) { return a.dis > b.dis;//每次让距离小出队 } }; vector<edge>e[maxn]; int dis[maxn];//记录最短路 bool vis[maxn];//记录是否找到最短路 int ans; void Dijkstra() { int s = 1;//s起点 根据情况改 for (int i = 0; i <= n; i++)dis[i] = INF, vis[i] = 0; dis[s] = 0; priority_queue<node>Q; Q.push(node(s, 0)); while (!Q.empty()) { node u = Q.top(); Q.pop(); if (vis[u.id])continue; vis[u.id] = 1; for (int i = 0; i < e[u.id].size(); i++) {//遍历邻居 edge y = e[u.id][i]; if (vis[y.v])continue; if (dis[y.v] > y.w + dis[u.id]) { dis[y.v] = y.w + u.dis; Q.push(node(y.v, dis[y.v]));//更新最短路 } } } } int main() { scanf("%d%d", &n, &m); int u, v, w; for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); e[u].push_back(edge(v, w)); if (u != v) e[v].push_back(edge(u, w)); } Dijkstra(); //for (int i = 1; i <= n; i++) printf("%d ", dis[i]); for (int i = 1; i <= n; i++) { int cnt = 0; for (int j = 0; j < e[i].size(); j++) { if (dis[i] == dis[e[i][j].v] + e[i][j].w) cnt++; else if (i >= e[i][j].v && dis[i] + e[i][j].w > dis[e[i][j].v] && dis[e[i][j].v] + e[i][j].w > dis[i]) ans++; //core } if (cnt > 1) ans++; } printf("%d", ans); return 0; }
B. 模拟题/公式题
其实就是给出日期,求过n天后的日期
#include <bits/stdc++.h> using namespace std; inline void read(int &a) { int ch = getchar(); while (ch < '0') ch = getchar(); a = 0; while (ch >= '0') a = a * 10 + ch - '0', ch = getchar(); } int M[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; void work() { int Mo, y, m, d; read(Mo); read(y); read(m); read(d); int del = 0; while (Mo < int(1e9)) { del++; Mo += del; if (++d > M[m] + (m == 2 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))) { d = 1; if (++m == 13) y ++, m = 1; } } printf("%d %d %d\n", y, m, d); } int main() { int T; read(T); while (T--) work(); return 0; }
C.下次一定
D.给出a,b,k,gcd(a,b)=1 求满足 方程 ax+by=c, ab<0的第k小的c