第九届河南理工大学算法程序设计大赛 正式赛(ABCDEFGHJKL)

ACcode

A. Asia区域赛

读题目输出奖牌之和就行,我把冠亚军也记成奖牌了。。

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);   
    int ans = 29 + 87 + 58 + 11 + 1 + 1;
    cout << ans << endl;

    return 0;
}
B. Asia区域制

二进制转化为十进制,当成字符串搞搞 “4位一并”

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);   
    int T;
    cin >> T;
    map<int, char> mp;
    mp[10] = 'a';
    mp[11] = 'b';
    mp[12] = 'c';
    mp[13] = 'd';
    mp[14] = 'e';
    mp[15] = 'f';
    while (T--) {
        string s;
        cin >> s;
        string t;
        int len = s.size();
        int last = len % 4;
        for (int i = 0; last && i < 4 - last; ++i) {
            s = "0" + s;
        }
        len = s.size();
        int tmp = 0;
        int cnt = 0;
        for (int i = 0; i < len; ++i) {
            ++tmp;
            cnt = cnt * 2 + s[i] - '0';
            if (tmp % 4 == 0) {
                // cout << tmp << endl;
                if (cnt <= 9) t += '0' + cnt;
                else t += mp[cnt];
                cnt = 0;
            }
        }
        cout << t << endl;
    }

    return 0;
}
C. Asia区域宫

每行每列只有一个障碍,只有存在一条对角线才可能把起点封住,读入点的时候预处理每种对角线的点数,如果存在点数合理就是NO,否者就是曼哈顿距离

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 10001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;

int n, m;
int sum[maxn];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    int T;
    cin >> T;
    while (T--) {
        mem(sum, 0);
        cin >> n >> m;
        for (int i = 0, x, y; i < m; ++i) {
            cin >> x >> y;
            sum[x+y-1]++;
        }

        int flag = 1;
        for (int i = 1; i <= n; ++i) {
            if (sum[i] == i) flag = 0;
        }

        if (flag) cout << "Yes " << 2*n - 2 << endl;
        else cout << "No\n";

    }
    return 0;
}
D. Asia区域阵

当时读题的时候感觉好难,数据给的很小,但是暴力的话感觉很难写,于是就放弃了。
补个暴力,枚举矩阵的起点然后计算以该点能扩展的最大矩阵,列扩展的时候需要标记,因为之后的列一定小于等于当前所能扩展的最小列

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1000001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;

char a[101][101];
int R[101][91], C[101][91];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 0; i < n; ++i) 
            scanf("%s", a[i]);
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                mem(R, 0);
                mem(C, 0);
                int c = m;
                for (int p = i; p < n; ++p) {
                    for (int k = j; k < c; ++k) {
                        int t = a[p][k];
                        if (R[p][t] || C[k][t]) {
                            c = k;
                            break;
                        }
                        ans = max(ans, (p-i+1)*(k-j+1));
                        R[p][t] = 1;
                        C[k][t] = 1;
                    }
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
E. Mo的游戏

统计每个字符出现的位置,然后for一遍,找最小的差(最小的差一定相邻)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

vector<int> g[1000];


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    string s;
    cin >> s;
    int len = s.size();
    for (int i = 0; i < len; ++i) {
        int t = s[i];
        g[t].push_back(i);
    }
    for (int i = 'a'; i <= 'z'; ++i) {
        if (g[i].empty()) continue;
        int ll = g[i].size();
        if (ll == 1) {
            cout << char(i) << ":0" << endl;
        }else {
            int tmp = g[i][1] - g[i][0];
            for (int j = 2; j < ll; ++j) {
                tmp = min(tmp, g[i][j] - g[i][j-1]);
            }
            cout << char(i) << ":" << len - tmp << endl;
        }
    }
    for (int i = 'A'; i <= 'Z'; ++i) {
        if (g[i].empty()) continue;
        int ll = g[i].size();
        if (ll == 1) {
            cout << char(i) << ":0" << endl;
        }else {
            int tmp = g[i][1] - g[i][0];
            for (int j = 2; j < ll; ++j) {
                tmp = min(tmp, g[i][j] - g[i][j-1]);
            }
            cout << char(i) << ":" << len - tmp << endl;
        }
    }

    return 0;
}
F. Mo的极限

字符串处理统计次方和对应的系数,最后找最大的判断

  • 分子上的系数可能全部为0
  • 可能存在相同指数的多项式,需要去重
  • 最简分数的分母是负数
  • 最简分数的分母是1
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;
struct ac{
    int d, x;
    bool operator < (const ac &t) {
        return x > t.x;
    }
}a[maxn], b[maxn];

void solve(string s, int &d, int &x) {
    int flag = 1;
    int len = s.size();
    if (s[0] == '-') flag = -1;
    int now = 0;
    if (s[0] == '+' || s[0] == '-') now = 1;
    int xx;
    for (int i = 0; i < len; ++i) {
        if (s[i] == '^') {
            xx = i + 1;
            break;
        }
    }
    int num = 0;
    for (int i = now; s[i] != 'x'; ++i) {
        num = num * 10 + s[i] - '0';
    }
    d = num * flag;
    num = 0;
    for (int i = xx; i < len; ++i) {
        num = num * 10 + s[i] - '0';
    }
    x = num;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  

    string s, t, tmp;
    cin >> s >> t;
    int lens, lent;
    int ls = s.size();
    int lt = t.size();
    int now = 1;
    map<int,int> mp;
    //处理第一个多项式
    for (int i = 0; i < ls; ++i) {
        if (i == ls-1 || (i && (s[i] == '+' || s[i] == '-'))) {
            if (i == ls-1) tmp += s[i];
            int d, x;
            solve(tmp, d, x);
            if (mp[x]) {//去重
                a[mp[x]].d += d;
                tmp = s[i];
                continue;
            }
            mp[x] = now;
            a[now].d = d;
            a[now++].x = x;
            tmp = s[i];
        }else tmp += s[i];
    }
    mp.clear();
    lens = now;
    now = 1;
    tmp = "";
	// 处理第二个多项式
    for (int i = 0; i < lt; ++i) {
        if (i == lt-1 || (i && (t[i] == '+' || t[i] == '-'))) {
            if (i == lt-1) tmp += t[i];
            int d, x;
            solve(tmp, d, x);
            if (mp[x]) {
                b[mp[x]].d += d;
                tmp = t[i];
                continue;
            }
            mp[x]=now;
            b[now].d = d;
            b[now++].x = x;
            tmp = t[i];
        }else tmp += t[i];
    }
    lent = now;
    sort(a+1, a + lens+1);
    sort(b+1, b + lent+1);
    int n, m = -1, a0, b0;
    for (int i = 1; i < lens; ++i) {
        if (a[i].d != 0) {
            a0 = a[i].d;            
            m = a[i].x;
            break;
        }
    }
    for (int i = 1; i < lent; ++i) {
        if (b[i].d != 0) {
            b0 = b[i].d;            
            n = b[i].x;
            break;
        }
    }    
    
    if (n > m) cout << 0 << endl;
    else if (n < m) cout << "oo\n";
    else {
        int tt = __gcd(abs(a0), abs(b0));
        a0 /= tt;
        b0 /= tt;
        if (b0 < 0) {
            b0 *= -1;
            a0 *= -1;
        }
        if (b0 == 1) cout << a0 << endl;
        else cout << a0 << "/" << b0 << endl;
    }
    
    return 0;
}
G. Mo的数学

容斥,初始化 a n s = n ! ans = n! ans=n!,然后筛m的素因子, 1 − n 1-n 1n中与 m m m互质的数一定不含有 m m m的素因子,容器奇数个素因子除掉,偶数个素因子乘上,每个素因子最多有 n t \frac{n}{t} tn
a n s 1 t × 2 t × . . . × n t t = a n s n t ! t n t \frac{ans}{1t × 2t ×...×\frac{n}{t}t} = \frac{ans}{\frac{n}{t}!t^\frac{n}{t}} 1t×2t×...×tntans=tn!ttnans
a n s × 1 t × 2 t × . . . × n t t = a n s × n t ! t n t ans ×{1t × 2t ×...×\frac{n}{t}t} = ans ×{\frac{n}{t}!t^\frac{n}{t}} ans×1t×2t×...×tnt=ans×tn!ttn

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1000001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
LL mod = 1e9 + 7;
LL jie[maxn];
LL exgcd(LL a, LL b, LL &x, LL &y) {
    LL d = a;
    if (b == 0) x = 1,y = 0;
    else {
        d = exgcd(b, a%b, y, x);
        y -= a / b * x;
    }
    return d;
}

LL inv(LL a, LL mod) {
    LL x, y;
    LL d = exgcd(a, mod, x, y);
    return (d == 1) ? ((x + mod) % mod) : -1; 
}

LL pow(LL x, LL a) {
    LL ans = 1;
    while (a) {
        if (a&1) ans = ans * x % mod;
        x = x * x % mod;
        a >>= 1;
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    int n, m;
    jie[1] = jie[0] = 1;
    for (LL i = 2; i < maxn; ++i) {
        jie[i] = jie[i-1] * i % mod;
    }
    while (cin >> n >> m) {
        vector<LL> su;
        for (LL i = 2; i * i <= m; ++i) {
            if (m % i == 0) {
                su.push_back(i);
                while (m % i == 0) m /= i;
            }
        }
        if (m > 1) su.push_back(m);

        LL ans = jie[n];
        int len = su.size();
        for (int i = 1; i < (1<<len); ++i) {
            int cnt = 0;
            LL t = 1; 
            for (int j = 0; (1<<j) <= i; ++j) {
                if (i & (1<<j)) {
                    cnt++;
                    t = t * su[j] % mod;
                }
            }
            LL x = jie[n/t] * pow(t, n/t) % mod;
            if (cnt & 1) ans = ans * inv(x, mod) % mod;
            else ans = ans * x % mod;
        }
        cout << ans << endl;        
    }
    
    return 0;
}
H. Mo的面积

只有两个矩形的矩形面积并,分类讨论相交矩形的长和宽

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct ac{
    int a, b, c, d;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    ac x, y;
    cin >> x.a >> x.b >> x.c >> x.d;
    cin >> y.a >> y.b >> y.c >> y.d;
    if (x.a > y.a) swap(x, y);
    int ans = 0;
    ans = (x.c - x.a) * (x.d - x.b);
    ans += (y.c - y.a) * (y.d - y.b);
    
    int l;
    if (y.a >= x.a && y.c <= x.c) l = y.c - y.a;
    if (y.a > x.a && y.c > x.c && y.a < x.c) l = x.c - y.a;
    if (y.a < x.a && y.c > x.a && y.c < x.c) l = y.c - x.a;
    if (y.a <= x.a && y.c >= x.c) l = x.c - x.a;
    if (y.c <= x.a || y.a >= x.c) l = 0;

    int r;
    if (y.b >= x.d || y.d <= x.b) r = 0;
    if (y.d >= x.d && y.b <= x.b) r = x.d - x.b;
    if (y.d <= x.d && y.b >= x.b) r = y.d - y.b;
    if (y.d > x.b && y.b < x.b && y.d < x.d) r = y.d - x.b;
    if (y.b > x.b && y.d > x.d && y.b < x.d) r = x.d - y.b;
    ans -= l * r;
    cout << ans << endl;

    return 0;
}
J. 简单递归

f [ n ] = 2 f [ n − 1 ] + f [ n − 2 ] 2 f[n] = 2f[n-1]+\frac{f[n-2]}{2} f[n]=2f[n1]+2f[n2]

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 105;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
int mod = 1e9 + 7;
LL f[1000006];
int main() {

    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);   
    int T;
    cin >> T;
    f[1] = f[2] = 1;
    for (int i = 3; i <= 1000000; ++i) {
        f[i] = (f[i-1] * 2 % mod) + (f[i-2] / 2 % mod);
        f[i] %= mod;
    }

    while (T--) {
        int n;
        cin >> n;
        cout << f[n] << endl;
    }

    return 0;
}
K. 高度期望

贪心把最小的树变成最大

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 105;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
    
int a[100005];
int main() {

    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);   
    
    int n, m;
    cin >> n >> m;
    int sum = 0;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        sum += a[i];
    }
    sort(a, a + n);
    int last = m * n - sum;
    int ans = 0;
    for (int i = 0; i < n && last > 0; ++i) {
        ans++;
        last -= 1000 - a[i];
    }
    cout << ans << endl;

    return 0;
}
L. 最优规划

并查集先把存在的边搞到一次,剩下的边从最小的边权开始看是否要加上

#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 100001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;

int fa[maxn];
int find(int x) {
    return (x == fa[x]) ? x : fa[x] = find(fa[x]);
}

int join(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if (fx == fy) return 0;
    if (fx > fy) swap(fx, fy);
    fa[fy] = fx;
    return 1;
}

struct ac{
    LL u, v, d;
    bool operator < (const ac &t) {
        return d < t.d;
    }
}a[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    int n, m, s;
    cin >> n >> m >> s;
    for (int i = 1; i <= n; ++i) fa[i] = i;
    for (int i = 0, u, v, d; i < m; ++i) {
        cin >> u >> v >> d;
        join(u, v);
    }
    LL ans = 0;
    for (int i = 0; i < s; ++i) {
        cin >> a[i].u >> a[i].v >> a[i].d;
    }

    sort(a, a + s);
    for (int i = 0; i < s; ++i) {
        int u = a[i].u;
        int v = a[i].v;
        LL d = a[i].d;
        int t = join(u, v);
        if (t) ans += d;
    }
    int flag = 1;
    for (int i = 1; i <= n && flag; ++i) {
        if (find(i) != find(1)) flag = 0;
    }
    if (flag) cout << ans << endl;
    else cout << "Concubines can't do it.\n";
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值