Educational Codeforces Round 82 (Rated for Div. 2)
A - Erasing Zeroes
水题,去记录第一个1出现的位置和最后一个1出现的位置,输出之间的0的数目
#include<bits/stdc++.h>
using namespace std;
char orin[200];
int main(void)
{
//freopen("abc.in","r",stdin);
int T, first, last, cnt;
scanf("%d", &T);
while (T--)
{
first = -1;
last = -1;
cnt = 0;
scanf("%s", orin);
for (int i = 0; orin[i]; ++i)
{
if (first == -1 && orin[i] == '1')
last = first = i;
else if (orin[i] == '1')
last = i;
}
if (first != -1)
{
for (int i = first; i <= last; ++i)
if (orin[i] == '0')
++cnt;
}
printf("%d", cnt);
if (T)
printf("\n");
}
}
B - National Project
去计算需要铺的好路的数目,用好路的数目除以好的日子向上取整-1算出一共循环的次数,再比较是否这些循环的日子里,坏日子所铺的路加上铺的好路的总数大于所需长度,如果不够,则要继续铺路直到达到要求
#include<bits/stdc++.h>
using namespace std;
long long n, g, b,t,good;
long long Ceil(long long a, long long b)
{
if (a % b == 0)
return a / b;
return a / b + 1;
}
int main(void)
{
int T;
long long result;
scanf("%d", &T);
while (T--)
{
scanf("%lld%lld%lld", &n, &g, &b);
t = n;
n = (n + 1) / 2;
result = Ceil(n, g) - 1;
good = result * (g + b) + n - result * g;
if (result * b + n < t)
good += t - result * b - n;
printf("%lld", good);
if (T)
printf("\n");
}
}
C - Perfect Keyboard
类似于数组建树的思想,每次如果有相邻的未访问过的字母,就把他放在前一个字母的左边或者右边,如果前一个字母的周围已经放置了两个字母,或者已访问字母的前一个字母不是他的周围已安置的字母,则输出NO,否则则从左到右输出安置字母,剩下未安置字母随意输出
#include<bits/stdc++.h>
int left[27], right[27];
char al[26];
bool vis[26];
char orin[300];
void P(int x)
{
if (left[x] != -1)
P(left[x]);
putchar(al[x]);
}
int main(void)
{
for (int i = 0; i < 26; ++i)
al[i] = i + 'a';
int T;
bool flag;
scanf("%d", &T);
while (T--)
{
flag = 1;
memset(left, -1, sizeof(left));
memset(right, -1, sizeof(right));
memset(vis, 0, sizeof(vis));
scanf("%s", orin);
vis[orin[0] - 'a'] = 1;
for (int i = 1; orin[i] && flag; ++i)
{
if (!vis[orin[i] - 'a'])
{
if (left[orin[i - 1] - 'a'] == -1 && right[orin[i] - 'a'] == -1)
{
left[orin[i - 1] - 'a'] = orin[i] - 'a';
right[orin[i] - 'a'] = orin[i - 1] - 'a';
}
else if (right[orin[i - 1] - 'a'] == -1)
{
right[orin[i - 1] - 'a'] = orin[i] - 'a';
left[orin[i] - 'a'] = orin[i - 1] - 'a';
}
else
flag = 0;
vis[orin[i] - 'a'] = 1;
}
else if (orin[i - 1] - 'a' != left[orin[i] - 'a'] && orin[i - 1] - 'a' != right[orin[i] - 'a'])
flag = 0;
}
if (!flag)
printf("NO");
else
{
printf("YES\n");
P(orin[0] - 'a');
for (int i = right[orin[0] - 'a']; i != -1; i = right[i])
putchar(al[i]);
for (int i = 0; i < 26; ++i)
if (!vis[i])
putchar(al[i]);
}
if (T)
putchar('\n');
}
}
D - Fill The Bag
本质上还是一个二进制的计算,看所给的数字能否填满需要数字m的二进制的空缺,这里用bit数组去记录各个位上拥有的数字数(这里计算时要加eps,否则会wa),然后遍历一次需要数字,如果需要则在对应的bit位上减1,再遍历一遍bit数组,大于等于2则后一位加上bit[i/2](合成过程),小于0,则向后寻找是否可以拆分,设拆分位置为i,起始位置为x,result+=i-x,如果没有可拆分的数字则输出NO
#include<bits/stdc++.h>
typedef long long ll;
ll n, m;
ll bit[65];
int result;
bool temp(int x)
{
for (int i = x + 1; i < 65; ++i)
{
if (bit[i]>0)
{
--bit[i];
for (int j = x; j < i; ++j)
++bit[j];
result += i - x;
return true;
}
}
return false;
}
int main(void)
{
int T, t, cnt;
bool flag;
scanf("%d", &T);
while (T--)
{
cnt = 0;
flag = 1;
result = 0;
memset(bit, 0, sizeof(bit));
scanf("%lld%lld", &n, &m);
for (int i = 0; i < m; ++i)
{
scanf("%d", &t);
++bit[int(log(t) / log(2)+1e-9)];
}
while (n)
{
if (n & 01)
--bit[cnt];
++cnt;
n >>= 1;
}
for (int i = 0; i < cnt; ++i)
{
if (bit[i] < 0)
{
if (!temp(i))
{
flag = 0;
break;
}
}
else if (bit[i] >= 2)
bit[i + 1] += bit[i] / 2;
}
if (flag)
printf("%d", result);
else
printf("-1");
if (T)
printf("\n");
}
}