Educational Codeforces Round 5(A,B,C,D)

Educational Codeforces Round 5(A,B,C,D)

tags: Codeforces


果然对于我这样的弱鸡来说还是Educational敲着比较畅快。然而因为自己的脑残在D题折腾了一下午,,,一对括号引发的血案~~(╯﹏╰)b

A.Comparing Two Long Integers

解析

比较两个超级大的数字的大小,去掉前导0后,剩下的长度越长数字越大,一样长的时候自然是用strcmp()进行字符串比较啦。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>

using namespace std;

#define MAXN    1000000+100
#define MOD     1000000007

char str1[MAXN], str2[MAXN];

int main()
{
    scanf("%s%s",str1,str2);
    int len1 = strlen(str1);
    int len2 = strlen(str2);

    int p1 = 0;
    while (p1 < len1&&str1[p1] == '0')
        p1++;
    len1 -= p1;
    int p2 = 0;
    while (p2 < len2&&str2[p2] == '0')
        p2++;
    len2 -= p2;

    int ans = 0;
    if (len1 != len2)
    {
        if (len1 > len2)
            ans = 1;
        else
            ans = -1;
    }
    else
    {
        ans = strcmp(&str1[p1],&str2[p2]);
    }
    if (ans == 0)
        printf("=\n");
    else if (ans == 1)
        printf(">\n");
    else if (ans == -1)
        printf("<\n");
    return 0;
}

B.Dinner with Emma

解析

显而易见,就是找每行中的最小值,然后取其中的最大值即可。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>

using namespace std;

#define MAXN    1000000+100
#define MOD     1000000007

int main()
{
    int m, n;
    scanf("%d%d", &n, &m);
    long long  maxc = 0;
    for (int i = 0; i < n; i++)
    {
        long long k;
        long long minc=1e10;
        for (int j = 0; j < m; j++)
        {
            scanf("%lld",&k);
            if (k < minc)
                minc = k;
        }
        if (minc > maxc)
            maxc = minc;
    }
    printf("%lld\n",maxc);
    return 0;
}

C.The Labyrinth

解析

先使用搜索预处理出每个’.’组成的连通分量的大小,并将连通分量编号,同时将每个‘.’所在连通分量的大小存在sz[MAXN][MAXN]数组中。

对于每个‘#’,统计和它相连的不同连通分量的大小,然后求和后取模即可得到该点的值。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>

using namespace std;

#define MAXN    1000+100
#define MOD     1000000007

int m, n;
int dir[4][2] = {
    {1,0},
    {-1,0},
    {0,1},
    {0,-1}
};
char mp[MAXN][MAXN];
int vis[MAXN][MAXN];
int sz[MAXN][MAXN];

struct node
{
    int x, y;
    node() {};
    node(int xx,int yy) :x(xx),y(yy){};
}nnode;

int bfs(int i,int j)
{
    queue<node> q,visited;
    vis[i][j] = 1;
    int cnt = 1;
    nnode.x = i; nnode.y = j;
    q.push(nnode);
    visited.push(nnode);
    while (!q.empty())
    {
        nnode = q.front();
        for (int i = 0; i < 4; i++)
        {
            int next_x = nnode.x + dir[i][0];
            int next_y = nnode.y + dir[i][1];
            if (next_x >= 0 && next_x < n&&next_y >= 0 && next_y < m&&mp[next_x][next_y] == '.'&&!vis[next_x][next_y])
            {
                vis[next_x][next_y] = 1;
                cnt++;
                q.push(node(next_x, next_y));
                visited.push(node(next_x, next_y));
            }
        }
        q.pop();
    }
    while (!visited.empty())
    {
        nnode = visited.front();
        vis[nnode.x][nnode.y] = i*m+j+1;
        sz[nnode.x][nnode.y] = cnt;
        visited.pop();
    }
    return cnt;
}
int NotFind(long long arr[],int len,int key)
{
    for (int i = 0; i < len; i++)
        if (arr[i] == key)
            return 0;
    return 1;
}
int main()
{
    memset(sz, 0, sizeof(sz));
    memset(vis, 0, sizeof(vis));
    scanf("%d%d", &n, &m);
    getchar();
    for (int i = 0; i < n; i++)
        scanf("%s",mp[i]);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mp[i][j] == '.'&&!vis[i][j])
            {
                bfs(i,j);
            }
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mp[i][j] == '*')
            {
                mp[i][j] = '0';
                long long cnt = 1;
                long long visited[5];
                int viscnt = 0;
                if (i - 1 >= 0 && NotFind(visited, viscnt, vis[i - 1][j])) { cnt += sz[i - 1][j]; visited[viscnt++] = vis[i - 1][j]; }
                if (i + 1 < n && NotFind(visited, viscnt, vis[i + 1][j])) { cnt += sz[i + 1][j]; visited[viscnt++] = vis[i + 1][j]; }
                if (j - 1 >= 0 && NotFind(visited, viscnt, vis[i][j - 1])) { cnt += sz[i][j - 1]; visited[viscnt++] = vis[i][j - 1]; }
                if (j + 1 < m&& NotFind(visited, viscnt, vis[i][j + 1])) { cnt += sz[i][j + 1]; visited[viscnt++] = vis[i][j + 1]; }
                cnt%= 10;
                mp[i][j] += cnt;
            }
        }
    }
    for (int i = 0; i < n; i++)
        printf("%s\n", mp[i]);
    return 0;
}

D.Longest k-Good Segment

这么水的题我竟然强行被坑了一天,,,,结果最后发现我只是宏定义的时候少加了个括号orz

解析

典型的two-pointers,先使用一个标记数组记录当前有哪些数,然后使用两个l,r标记当前左边界和右边界接着不断重复以下两步直到r==n-1:
1. 将右边界右移,直到当前不同的数的数目满足cnt>k
2. 将左边界右移,直到cnt<=k重新满足
期间维护一个满足条件的最大长度即可。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>

using namespace std;

#define MAXN    500100
#define MOD     1000000007

int arr[MAXN];
int vis[MAXN * 2];

int main()
{
    memset(vis, 0, sizeof(vis));
    int n, k;
    scanf("%d%d",&n,&k);
    for (int i = 0; i < n; i++)
    {
        scanf("%d",&arr[i]);
    }
    int maxlen = 0;
    int ml=0, mr=0;
    int cnt = 1;
    int l = 0, r = 0;   //区间左端点和右端点下标
    vis[arr[0]] = 1;
    while (r<n)
    {
        int flag = (vis[arr[r + 1]] == 0) ? 1 : 0;
        while (cnt + flag <= k)
        {
            cnt += flag;
            vis[arr[r + 1]] ++;
            r++;
            if (r >= n - 1)
                break;
            flag = (vis[arr[r + 1]] == 0) ? 1 : 0;
        }
        if ((r - l + 1)>maxlen)
        {
            maxlen = (r - l + 1);
            ml = l; mr = r;
        }
        vis[arr[l]]--;
        if (vis[arr[l]] == 0)   //如果删除arr[l]后对应位置值为0,说明当前范围内不再有arr[l],需要修改cnt
            cnt--; 
        l++;
    }
    printf("%d %d\n",ml+1,mr+1);
    return 0;
}

声明

原文在CSDN上,链接http://blog.csdn.net/lincifer/article/details/50551482

还有我那连域名都还没有的博客上也有一份,链接http://115.28.240.133:8080/archives/96

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值