NEU12月个人练习赛总结

来源:互联网 发布:快易宝软件下载 编辑:程序博客网 时间:2024/04/30 09:53

这么水的题目居然没有做完真是愧对党的培养。只好拿期末没时间刷题码力下降来安慰下自己。弱鸡还是要多努力啊~~希望下一下不要在题数上被碾了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 8111111long 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;}


0 0
原创粉丝点击