Codeforces Educational Round 5

Codeforces Educational Round 5
通过数: 4
Standing: 196/4176
题目链接: http://codeforces.com/contest/616
A:
两个大数,可能有首0.
问哪个数大

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1000000 + 6;
char s1[MAXN], s2[MAXN];
int main()
{
    while(scanf("%s%s", s1, s2) != EOF){
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        int t1 = 0, t2 = 0;
        while(s1[t1] == '0')    t1++;
        while(s2[t2] == '0')    t2++;
        if(len1 - t1 > len2 - t2)   printf(">\n");
        else if(len1 - t1 < len2 - t2) printf("<\n");
        else{
            int flag = 0;
            for(int i = 0 ; i < len1 - t1 ; i++){
                if(s1[i + t1] > s2[i + t2]){flag = 1; break;}
                else if(s1[i + t1] < s2[i + t2]){flag = -1; break;}
            }
            if(flag == 1)   printf(">\n");
            else if(flag == -1) printf("<\n");
            else printf("=\n");
        }
    }
    return 0;
}

B:
题目写的很复杂,剥壳以后就是每一行的最小值的最大值。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define inf (1000000007)
const int MAXN = 100 + 5;
int c[MAXN][MAXN];
int mmax[MAXN];
int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        int ans = 0;
        for(int i = 1 ; i <= n ; i++){
            mmax[i] = inf;
            for(int j = 1 ; j <= m ; j++)   scanf("%d", &c[i][j]), mmax[i] = min(mmax[i], c[i][j]);
            ans = max(ans, mmax[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}

C:
一个矩阵上,一些点空格一些点有障碍。
问对于每个障碍,如果障碍不见了,它与原先的图能够成的连通子块里面有多少个点。
把原图做一个连通分量标号,两边dfs就可以。第一遍计数,第二遍标号。
忘记输出数要%10 WA了两发

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1000 + 5;
char str[MAXN][MAXN];
int vis[MAXN][MAXN];
int cnt;
int id[MAXN][MAXN], id_cnt;
int num[MAXN * MAXN];
int n, m;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool valid(int x, int y)
{
    if(x < 1 || x > n)  return false;
    if(y < 1 || y > m)  return false;
    return true;
}
void dfs1(int x, int y)
{
    vis[x][y] = 1;
    cnt++;
    for(int i = 0 ; i < 4 ; i++){
        int tx = dx[i] + x;
        int ty = dy[i] + y;
        if(valid(tx, ty) && vis[tx][ty] == 0 && str[tx][ty] == '.'){
            dfs1(tx, ty);
        }
    }
}
void dfs2(int x, int y)
{
    vis[x][y] = 2;
    id[x][y] = id_cnt;
    for(int i = 0 ; i < 4 ; i++){
        int tx = dx[i] + x;
        int ty = dy[i] + y;
        if(valid(tx, ty) && vis[tx][ty] < 2 && str[tx][ty] == '.'){
            dfs2(tx, ty);
        }
    }
}
int a[5];
int main()
{
    while(scanf("%d%d", &n, &m) != EOF){
        for(int i = 1 ; i <= n ; i++) scanf("%s", str[i] + 1);
        id_cnt = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 1 ; i <= n ; i++){
            for(int j = 1 ; j <= m ; j++){
                if(vis[i][j] || str[i][j] == '*')   continue;
                cnt = 0;
                dfs1(i, j);
                num[++id_cnt] = cnt;
                dfs2(i, j);
            }
        }
        for(int i = 1 ; i <= n ; i++){
            for(int j = 1 ; j <= m ; j++){
                if(str[i][j] == '.') printf(".");
                else{
                    int tcnt = 0;
                    a[0] = 0;
                    for(int k = 0 ; k < 4 ; k++){
                        int tx = dx[k] + i;
                        int ty = dy[k] + j;
                        if(valid(tx, ty) && str[tx][ty] == '.')
                            a[tcnt++] = id[tx][ty];
                    }
                    if(tcnt == 0){
                        printf("1");
                        continue;
                    }
                    sort(a, a + tcnt);
                    int ans = num[a[0]];
// if(i == n && j == m) printf("%d\n", ans);
                    for(int k = 1 ; k < tcnt ; k++){
                        if(a[k] != a[k - 1]) ans += num[a[k]];
// if(i == n && j == m) printf("%d\n", ans);
                    }
                    printf("%d", (ans+1) % 10);
                }
            }
            printf("\n");
        }
    }
    return 0;
}

D:
问最长的序列,里面不同的数不超过k个。
开头尾指针O(2*n)就可以,不明白为什么不是第三题

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1e6 + 5;
int vis[MAXN], a[MAXN];
int main()
{
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF){
        memset(vis, 0, sizeof(vis));
        int cnt = 0;
        int pre = 1;
        int ans = 1, x, y;
        x = y = 1;
        for(int i = 1 ; i <= n ; i++){
            scanf("%d", &a[i]);
            if(vis[a[i]] == 0) cnt++;
            vis[a[i]]++;
            while(cnt > k && pre <= i){
                vis[a[pre]]--;
                if(vis[a[pre]] == 0) cnt--;
                pre++;
            }
            if(ans < i - pre + 1) ans = i - pre + 1, x = pre, y = i;
        }
        printf("%d %d\n", x, y);
    }
    return 0;
}

E:
题意是问n%1 + n%2 + .. + n%m等于多少(n,m <= 1e13)
打表找规律,没有规律。想到了大概能转换成ans = n*m - n/i*i的形式,n/i对于一段区间是一个定数所以可以做。但是发现n/i也可能很大,然后就跪了。
标解。发现对于n/i*i,要么n/i <= sqrt(n),要么i <= sqrt(n)。故原值分为两段。I

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
#define mod (1000000007)
LL ppow(LL a, int x)
{
    a %= mod;
    LL ans = 1;
    for(int i = x ; i ; i >>= 1){
        if(i & 1) ans = (ans * a) % mod;
        a = (a * a) % mod;
    }
    return ans;
}
LL mul(LL u, LL v)
{
    return (u % mod) * (v % mod) % mod;
}
LL rev(LL a){return ppow(a, mod - 2);}
LL cal(LL l, LL r){return mul(mul((l + r), (r - l + 1)), rev(2));}
LL divise(LL u){return (u % mod + mod) % mod;}
int main()
{
    LL n, m;
    while(scanf("%I64d%I64d", &n, &m) != EOF){
        LL sn = sqrt(1.0 * n);
//        printf("sn = %I64d\n", sn);
        LL ans = 0;
        for(LL i = 1 ; i <= min(sn, m) ; i++){
            ans = (ans + mul(n / i, i)) % mod;
        }
//        printf("ans1 = %I64d\n", ans);
//        LL ans2 = 0;
//        printf("sn = %I64d\n", sn);
        int f = 1;
        LL i = sn;
//        printf("second\n");
//        printf("%I64d\n", n / (i + 1) + 1);
        while(n / (i + 1) + 1 <= sn){
            i--;
//            printf("i = %I64d", i);
//            system("pause");
        }
//        printf("second\n");
        for(; i >= 1 ; i--){
            int flag = 0;
            LL r = floor(1.0 * n / i);
            if(r >= m) r = m, flag = 1;
            LL l = floor(1.0 * n / (i + 1)) + 1;
            if(l > m) break;
//            if(f){
//                printf("l = %I64d, r = %I64d\n", l, r);
//                f = 0;
//            }
//            printf("i = %I64d, l = %I64d, r = %I64d, ans2 = %I64d\n", i, l, r, ans2);
            ans = (ans + mul(i, cal(l, r))) % mod;
//            if(flag){
//                printf("i = %I64d, l = %I64d, r = %I64d\n", i, l, r);
//            }
            if(flag)    break;
        }
        printf("%I64d\n", divise(mul(n, m) - ans));
    }
    return 0;
}
改进版
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
#define mod (1000000007)
#define MAXN (2000000)
LL ppow(LL a, int x)
{
    a %= mod;
    LL ans = 1;
    for(int i = x ; i ; i >>= 1){
        if(i & 1) ans = (ans * a) % mod;
        a = (a * a) % mod;
    }
    return ans;
}
LL mul(LL u, LL v)
{
    return (u % mod) * (v % mod) % mod;
}
LL rev(LL a){return ppow(a, mod - 2);}
LL cal(LL l, LL r){return mul(mul((l + r), (r - l + 1)), rev(2));}
LL divise(LL u){return (u % mod + mod) % mod;}
int main()
{
    LL n, m;
    while(scanf("%I64d%I64d", &n, &m) != EOF){
        LL ans = 0;
        LL rec = m + 1;
        for(LL i = 1 ; i < MAXN ; i++){
            LL l = n / (i + 1) + 1;
            LL r = min(n / i, m);
            if(l > r) continue;
// printf("l = %I64d, r = %I64d\n", l, r);
            rec = min(l, rec);
            ans = (ans + mul(i, cal(l, r))) % mod;
        }
// printf("ans = %I64d\n", ans);
// printf("rec = %I64d\n", rec);
        for(LL i = 1 ; i < rec ; i++){
            ans = (ans + n - n % i) % mod;
        }
        printf("%I64d\n", divise(mul(n, m) - ans));
    }
    return 0;
}

你可能感兴趣的:(Codeforces Educational Round 5)