Problem K:Kindergarten Physics
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6812
这题算是比较坑了,刚开始想着还要用公式推一推,本身物理就不好,只好放掉了。赛后才发现这题只要原样输出即可,因为要求的误差完全可以满足😂;
#include<iostream> using namespace std; int main(){ int T,a,b,d,t; scanf("%d",&T); while(T --) { scanf("%d%d%d%d",&a,&b,&d,&t); printf("%d\n",d); } return 0; }
Problem D:Deliver the Cake
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6805
这题还是看得比较明白的,当时也尝试过了,可惜还是t了。最近刚学完基础的图论,遇到这种很直白的图论题还是想试试身手的。一开始写了个dijstra,心思比较单纯,直接t了。后面想改优先级队列,不过不太会写,找了一些板子,本来都快出来了,才发现自己关于左右手这一块漏想了一种情况。题解看不太懂,网上找了一篇比较明白的,把每个点一分为二,用以表示左右手两种情况或者说是状态。反正最后就是优先级队列+dijstra,这一块还不熟,一知半解。暂时先放着,最近在学算法竞赛进阶指南,日后再看到图论部分再回来解决。
#include<iostream> #include<queue> #include<vector> typedef long long LL; using namespace std; const int MAXN = 200005; struct Edge { int v, w; }; struct Node { LL d; int u, t; bool operator<(const Node &n) const { return d > n.d; } }; vector<Edge> edge[MAXN]; LL dis[MAXN][2]; int T, n, m, s, t, x; char str[MAXN]; priority_queue<Node> pq; int main() { for (scanf("%d", &T); T--;) { scanf("%d%d%d%d%d", &n, &m, &s, &t, &x); scanf("%s", str + 1); for (int i = 1; i <= m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); edge[u].push_back(Edge { v, w }); edge[v].push_back(Edge { u, w }); } for (int i = 1; i <= n; i++) dis[i][0] = dis[i][1] = 1e18; if (str[s] != 'R') pq.push(Node { dis[s][0] = 0, s, 0 }); if (str[s] != 'L') pq.push(Node { dis[s][1] = 0, s, 1 }); while (!pq.empty()) { Node d = pq.top(); pq.pop(); if (dis[d.u][d.t] < d.d) continue; if (d.u == t) break; for (const Edge &e : edge[d.u]) { LL w = e.w + d.d; int t = str[e.v] == 'R' ? 1 : (str[e.v] == 'L' ? 0 : d.t); if (t == d.t && w < dis[e.v][t]) pq.push(Node { dis[e.v][t] = w, e.v, t }); w += x; if (str[e.v] == 'M') t = !t; if (t != d.t && w < dis[e.v][t]) pq.push(Node { dis[e.v][t] = w, e.v, t }); } } printf("%lld\n", min(dis[t][0], dis[t][1])); while (!pq.empty()) pq.pop(); for (int i = 1; i <= n; i++) edge[i].clear(); } return 0; }
Problem E:Equal Sentences
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6806
这道题目本身并不难,可惜当时我看不懂题意,读题能力还是太差了😶。如果仔细观察,不难发现如果一个序列相邻元素两两不同,那么方案数就是斐波那契数列,至于答案就是这些可以划分出的斐波那契数列的乘积了。
#include<iostream> typedef long long LL; using namespace std; const int MAXN = 200005, MOD = 1e9 + 7; LL f[MAXN]; int T, n; string aa[MAXN]; char str[MAXN]; int main(){ f[0]=1,f[1]=1; for(int i=2;i<=1e5;i++) f[i]=(f[i-1]+f[i-2])%MOD; for(scanf("%d",&T);T--;){ scanf("%d",&n); int cnt=0; LL ans=1; for(int i=1;i<=n;i++){ scanf("%s",str); aa[i]=str; if(aa[i]!=aa[i-1])++cnt; else ans =ans*f[cnt]% MOD,cnt=1; } ans = ans * f[cnt] % MOD; printf("%lld\n", ans); } return 0; }