当前位置: 首页 > 工具软件 > neu.Node > 使用案例 >

NEU12月个人练习赛总结

傅浩漫
2023-12-01

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


 类似资料: