Codeforces Educational Round 5 ABCDE

来源:互联网 发布:淘宝自己的评价不见了 编辑:程序博客网 时间:2024/06/06 00:21

套题链接:http://codeforces.com/contest/616

难度类型:难度上有错位,个人觉得B比A简单,D比C简单,E是数论。BD的代码量较少,AC较多。

A

题解

类型:大数,模拟

大数的比较,一开始Java大数乱搞TLE了。
然后反正就改成手写的比较,前导零忽略掉然后比长度,比字典序。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headconst int N = 1e6+5;char a[N];char b[N];int main(){    gets(a);    gets(b);    char *sa = a, *sb = b;    while (*sa == '0') sa++;    while (*sb == '0') sb++;    int la = strlen(sa), lb = strlen(sb);    if (la != lb) {        puts(la < lb ? "<" : ">");        return 0;    }    int val = strcmp(sa, sb);    if (val < 0) {        puts("<");    } else if (val == 0) {        puts("=");    } else {        puts(">");    }    return 0;}

B

题解

类型:模拟

每行最小值的最大值,读懂题就行了。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headint main(){    int n, m, x, ans = 0;    scanf("%d%d", &n, &m);    for (int i = 0; i < n; i++) {        int mn = 1e9+5;        for (int j = 0; j < m; j++) {            scanf("%d", &x);            mn = min(mn, x);        }        ans = max(ans, mn);    }    printf("%d\n", ans);    return 0;}

C

题解

类型:并查集/搜索

主流做法是搜索处理答案或用并查集合并来处理,要算的就是每个空的点的连通块大小。

我用了并查集,做答案的话就是对每个占位的点将四周的点再和它合并,我用set来做这个,因为直接在并查集里面合并会影响到并查集的结构。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headconst int N = 1000+5;const int M = 1000000+5;int fa[M];int cnt[M];char s[N][N];int pos[N][N];int res[N][N];int find(int key) {    return (key == fa[key]) ? key : (fa[key] = find(fa[key]));}void init(int n) {    for (int i = 1; i <= n; i++) {        fa[i] = i;        cnt[i] = 1;    }}void joint(int u, int v) {    int a = find(u), b = find(v);    if (a != b) {        fa[a] = b;        cnt[b] += cnt[a];    }}bool same(int u, int v) {    return find(u) == find(v);}int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};int n, m;PII mov(PII &cur, int dir) {    return mp(cur.fi+dx[dir], cur.se+dy[dir]);}bool isok(PII &cur) {    return cur.fi > 0 && cur.fi <= n && cur.se > 0 && cur.se <= m;}int main(){    scanf("%d%d", &n, &m);    init(n*m);    for (int i = 1; i <= n; i++) {        scanf("%s", s[i]+1);        for (int j = 1; j <= m; j++) {            pos[i][j] = (i-1)*m+j;        }    }    for (int i = 1; i <= n; i++) {        for (int j = 1; j <= m; j++) {            if (s[i][j] == '*') continue;            for (int dir = 0; dir < 4; dir++) {                PII to = mp(i+dx[dir], j+dy[dir]);                if (!isok(to) || s[to.fi][to.se] == '*') continue;                joint(pos[i][j], pos[to.fi][to.se]);            }        }    }    set<int> se;    for (int i = 1; i <= n; i++) {        for (int j = 1; j <= m; j++) {            if (s[i][j] != '*') continue;            int ans = 1;            for (int dir = 0; dir < 4; dir++) {                PII to = mp(i+dx[dir], j+dy[dir]);                if (!isok(to) || s[to.fi][to.se] == '*') continue;                int temp = find(pos[to.fi][to.se]);                if (se.find(temp) == se.end()) {                    ans += cnt[temp];                    se.insert(temp);                }            }            res[i][j] = ans % 10;            se.clear();        }    }    for (int i = 1; i <= n; i++) {        for (int j = 1; j <= m; j++) {            putchar((s[i][j] == '*') ? '0' + res[i][j] : '.');        }        puts("");    }    return 0;}

D

题解

类型:模拟,数据维护,尺取法

数据只有六次方,非法存在传递性,因此尺取法乱搞就行了。

维护一个数组cnti表示值为i的数当前有多少个。

移动右边的指针,找左边的最优解,同时维护cnt数组具体可以参照代码或者《挑战》。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headconst int N = 1e6+5;int a[N];int cnt[N];int main(){    int k, n;    int ansl, ansr, ans = 0;    int l = 1, cur = 0;    scanf("%d%d", &n, &k);    for (int i = 1; i <= n; i++) {        scanf("%d", a+i);        if (cnt[a[i]]++ == 0) cur++;        while (cur > k) {            if (cnt[a[l]]-- == 1) cur--;            l++;        }        if (i-l+1 > ans) {            ansl = l, ansr = i, ans = i-l+1;        }    }    printf("%d %d\n", ansl, ansr);    return 0;}

E

题解

类型:数论

(i=1mnmodi)mod109+7

由于main函数一处乘法没有对n取模,非常可惜没能在场上A掉,赛后五分钟一下就看到了。

具体的做法就是说分块,算等差,复杂度是对数的。此题很适合暴力对拍。

具体推导过程可看我另一篇:http://blog.csdn.net/xc19952007/article/details/50528187

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headconst LL MOD = 1e9+7;LL ck(LL n, LL m) {    LL ans = 0;    for (int i = 1; i <= m; i++) {        ans += (n%i);        ans %= MOD;    }    return ans;}LL solve(LL n, LL m) {    LL be = 1, en, mul, ans = 0;    while (be <= m) {        mul = n/be;        en = min(n/mul, m);        LL cur = n%be;        LL num = (MOD+en-be)%MOD;        ans += (MOD + cur + cur-num*mul%MOD) % MOD * (num+1) % MOD;        ans %= MOD;        be = en+1;    }    return ans * powmod(2, MOD-2, MOD) % MOD;}int main(){    LL n, m;    scanf("%I64d%I64d", &n, &m);    LL ans = 0;    if (m > n) {        ans = (MOD+m-n)%MOD * (n%MOD) % MOD;    }    ans = ans+solve(n, min(m, n));    printf("%I64d\n", ans%MOD);    return 0;}
0 0
原创粉丝点击