这么水的题目居然没有做完真是愧对党的培养。只好拿期末没时间刷题码力下降来安慰下自己。弱鸡还是要多努力啊~~希望下一下不要在题数上被碾了ORZ
题目链接:
A
http://acm.neu.edu.cn/hustoj/problem.php?id=1664
和15年沈阳站的最后一道神似,建图如出一辙,把每个集合增加一个点就可以了。
#include <bits/stdc++.h> using namespace std; #define maxn 1111111 #define maxm 5111111 #define INF 11111111111111111 int n, m, s, f, p; struct node { int u, v, next; long long w; }edge[maxm]; int head[maxn], cnt; void add_edge (int u, int v, int w) { //cout << u << " " << v << endl; edge[cnt].u = u, edge[cnt].v = v, edge[cnt].w = w, edge[cnt].next = head[u], head[u] = cnt++; return ; } long long d1[maxn], d2[maxn]; bool vis[maxn]; int top, num[maxn]; bool spfa (int start, long long *d) { memset (vis, 0, sizeof vis); for (int i = 1; i <= n+m; i++) { d[i] = INF; } vis[start] = 1; d[start] = 0; queue <int> q; while (!q.empty ()) q.pop (); q.push (start); memset (num, 0, sizeof num); num[start] = 1; while (!q.empty ()) { int u = q.front (); q.pop (); vis[u] = 0; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (d[v]>d[u]+edge[i].w) { d[v] = d[u]+edge[i].w; if (!vis[v]) { vis[v] = 1; q.push (v); if (++num[v] > n+m) return 0; } } } } return 1; } int main () { //freopen ("in.txt", "r", stdin); while (scanf ("%d%d%d%d%d", &n, &m, &s, &f, &p) == 5) { memset (head, -1, sizeof head); cnt = 0; for (int i = 1; i <= m; i++) { int x, u, v; long long w; scanf ("%lld%d", &w, &x); for (int j = 1; j <= x; j++) { scanf ("%d", &u); add_edge (u, i+n, w); add_edge (i+n, u, 0); } } spfa (s, d1); //for (int i = 1; i <= n; i++) cout << d1[i] << " "; cout << endl; spfa (f, d2); //for (int i = 1; i <= n; i++) cout << d2[i] << " "; cout << endl; if (d1[f] == INF || d2[p] == INF) printf ("Poor guy, you don’t have enough Money!\n"); else printf ("%lld\n", d1[f]+d2[p]); } }
B
http://acm.neu.edu.cn/hustoj/problem.php?id=1665
大水题啊有木有,结果上来理解错题目了,怎么想都有27种情况吧,然后后来发现,尼玛一样的情况视为一种,也是啊同样的密码如果错掉了一次怎么可能再错第二次。被自己蠢哭了~于是乎string暴力
#include <bits/stdc++.h> using namespace std; int main () { //freopen ("in.txt", "r", stdin); string a[3][3]; string ans; while (cin >> a[0][0]) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (i == 0 && j == 0) continue; cin >> a[i][j]; } } cin >> ans; string gg[111]; int cnt = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { string cur = a[0][i] + a[1][j] + a[2][k]; bool ok = 0; for (int l = 0; l < cnt; l++) { if (gg[l] == cur) { ok = 1; break; } } if (!ok) { gg[cnt++] = cur; } } } } if (cnt <= 6) { printf ("1/1\n"); continue; } int g = __gcd (6, cnt); printf ("%d/%d\n", 6/g, cnt/g); } return 0; }
C
http://acm.neu.edu.cn/hustoj/problem.php?id=1666
都是泪啊~刚开始用map写超时了(最后证明超时的原因是因为我第一个a[0]的输入用了cin),然后就一直不敢map了,然后一直在用二分离散化什么的瞎搞,搞对了自己出的数据死活过不去。然后学长告诉我他就是map写的,最后还剩10多分钟的时候重写map发现WA,最后结束了发现是自己把a数组开成long long但是a[0]输入用了%d。又一次被自己蠢哭~
#include <bits/stdc++.h> using namespace std; #define maxn 8111111 long long a[33]; long long sum[111111]; long long num[111111]; char s[111111]; map <long long, long long> gg; int main () { //freopen ("in.txt", "r", stdin); while (scanf ("%lld", &a[0]) == 1) { for (int i = 1; i < 26; i++) { scanf ("%lld", &a[i]); } scanf ("%s", s); long long ans = 0; int n = strlen (s); for (int i = 0; i < n; i++) { num[i] = a[s[i]-'a']; sum[i] = (i == 0 ? 0 : sum[i-1]) + num[i]; } for (int i = 0; i < 26; i++) { gg.clear (); for (int j = 0; j < n; j++) { if (s[j] == 'a' + i) { if (gg.count (sum[j]-a[i])) { ans += gg[sum[j]-a[i]]; } if (gg.count (sum[j])) { gg[sum[j]]++; } else gg[sum[j]] = 1; } } } printf ("%lld\n", ans); } return 0; }
D
http://acm.neu.edu.cn/hustoj/problem.php?id=1667
题意很坑,按照我自己的ac代码题意应该是这样的:求最长的合法子序列(不必连续),答案就是这个合法子序列的匹配数也就是长度除以2.
裸地区间DP如果头尾匹配就匹配,然后在枚举中间断点更新DP值。
#include <bits/stdc++.h> using namespace std; #define maxn 111 int dp[maxn][maxn]; char a[maxn]; bool ok (char a, char b) { if (a == '#' && b == '*') return 1; else if (a== '%' && b == '&') return 1; return 0; } int main () { //freopen ("in.txt", "r", stdin); int t; scanf ("%d", &t); while (t--) { scanf ("%s", a); memset (dp, 0, sizeof dp); int n = strlen (a); //cout << n << endl; for (int l = 1; l < n; l++) { for (int i = 0; i+l < n; i++) { int j = l+i; if (ok (a[i], a[j])) { dp[i][j] = max (dp[i+1][j-1]+1, dp[i][j]); } //dp[i][j] = max (dp[i][j], max (dp[i+1][j], dp[i][j-1])); for (int k = i+1; k <= j; k++) { dp[i][j] = max (dp[i][j], dp[i][k-1]+dp[k][j]); } } } printf ("%d\n", dp[0][n-1]); } return 0; }
E
http://acm.neu.edu.cn/hustoj/problem.php?id=1668
判断点在三角形里面还是外面还是边上。
这道题又一次充分了证明了自己有多蠢,有理有据令人信服。
第一次写成了ok[0]==ok[1]==ok[2]T.T,第二次发现有一个输出少打了一个点。。。
这么简单的题目其实什么姿势都能过,我是判断了三次点在线段上和点在直线左侧的to_left_test测试。
#include <bits/stdc++.h> using namespace std; bool ok[3]; typedef unsigned long long ll; #define maxn 111111 #define pi acos (-1) #define rotate Rotate const double eps = 1e-8; int dcmp (double x) { if (fabs (x) < eps) return 0; else return x < 0 ? -1 : 1; } struct point { double x, y; point (double _x = 0, double _y = 0) : x(_x), y(_y) {} point operator - (point a) const { return point (x-a.x, y-a.y); } point operator + (point a) const { return point (x+a.x, y+a.y); } bool operator < (const point &a) const { return x < a.x || (x == a.x && y < a.y); } bool operator == (const point &a) const { return dcmp (x-a.x) == 0 && dcmp (y-a.y) == 0; } }a[3], b; point operator * (point a, double p) { return point (a.x*p, a.y*p); } double cross (point a, point b) { return a.x*b.y-a.y*b.x; } double dot (point a, point b) { return a.x*b.x + a.y*b.y; } bool OnSegment (point p, point a1, point a2) { return dcmp (cross (a1-p, a2-p) == 0) && dcmp (dot (a1-p, a2-p) <= 0); } bool ToLeftTest (point a, point p1, point p2) { return (cross (a-p1, p2-p1) >= 0); } int main () { //freopen ("in.txt", "r", stdin); int t; cin >> t; while (t--) { cin >> b.x >> b.y; for (int i = 0; i < 3; i++) { cin >> a[i].x >> a[i].y; } for (int i = 0; i < 3; i++) { if (OnSegment (b, a[i], a[(i+1)%3])) { cout << "Not quite clear..." << endl; goto out; } } for (int i = 0; i < 3; i++) { ok[i] = ToLeftTest (b, a[i], a[(i+1)%3]); } //cout << ok[0] << " " << ok[1] << " " << ok[2] << endl; if (ok[0] == ok[1] && ok[1] == ok[2]) { cout << "Here it is!" << endl; } else cout << "Can't find it." << endl; out: ; } return 0; }
F
http://acm.neu.edu.cn/hustoj/problem.php?id=1669
小模拟,2048火的时候玩烂了都,毫无问题~多玩玩游戏还是好的哈哈
#include <bits/stdc++.h> using namespace std; #define maxn 11 int mp[maxn][maxn]; int main () { //freopen ("in.txt", "r", stdin); int t; scanf ("%d", &t); while (t--) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { scanf ("%d", &mp[i][j]); } } int q; scanf ("%d", &q); while (q--) { int op; scanf ("%d", &op); //cout << ".." << endl; if (op == 1) { for (int i = 0; i < 4; i++) {//列数 for (int k = 1; k < 4; k++) {//行数 int j = k; while (j > 0) { if (mp[j-1][i] == 0) { //移动 swap (mp[j-1][i], mp[j][i]); } else if (mp[j-1][i] == mp[j][i]) { //合并 mp[j-1][i] *= 2; mp[j][i] = 0; break; } else break; j--; } } } } else if (op == 2) { for (int i = 0; i < 4; i++) { for (int k = 2; k >= 0; k--) { int j = k; while (j < 3) { if (mp[j+1][i] == 0) { swap (mp[j+1][i], mp[j][i]); } else if (mp[j+1][i] == mp[j][i]) { mp[j+1][i] *= 2; mp[j][i] = 0; break; } else break; j++; } } } } else if (op ==3) { for (int i = 0; i < 4; i++) { for (int k = 1; k < 4; k++) { int j = k; while (j > 0) { if (mp[i][j-1] == 0) { swap (mp[i][j-1], mp[i][j]); } else if (mp[i][j-1] == mp[i][j]) { mp[i][j-1] *= 2; mp[i][j] = 0; break; } else break; j--; } } } } else if (op == 4) { for (int i = 0; i < 4; i++) { for (int k = 2; k >= 0; k--) { int j = k; while (j < 3) { if (mp[i][j+1] == 0) { swap (mp[i][j+1], mp[i][j]); } else if (mp[i][j+1] == mp[i][j]) { mp[i][j+1] *= 2; mp[i][j] = 0; break; } else break; j++; } } } } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { printf ("%5d", mp[i][j]); } printf ("\n"); } printf ("\n"); } } return 0; }