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