Codeforces Round #327 (div.2)
tags: Codeforces
A. Wizards’ Duel
题意:
两个物体在长l的走廊两端分别以p,q的速度相向运动,第一次遇到时这两个物体将转向,到走廊两端时再转向,期间速度不变,问第二次相遇时的位置
解析:
实际上第二次相遇的位置和第一次是相同的,只要算出第一次相遇的地点就好.
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
int l,p,q;
scanf("%d%d%d",&l,&p,&q);
double ans = (1.0*l*p) / (p + q);
printf("%.4lf\n",ans);
return 0;
}
B. Rebranding
题意:
给定长为n的字符串,与m次操作,每次操作读入两个字符a,b,将字符串中的所有字符a变为b,所有b变为a,输出操作完后的字符串
解析:
在原字符串上操作m次显然不行.实际上只需要对26个字母进行操作,用m次操作修改其对应关系,确定每个字母在执行完所有操作后对应的字母,然后输出对应的字符串即可.
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
char ch[26];
char str[210000];
int main(int argc, char *argv[])
{
for (int i = 0; i < 26; i++)
{
ch[i] = 'a' + i;
}
int len, m;
char a, b;
scanf("%d%d", &len, &m);
scanf("%s", str);
getchar();
for (int i = 0; i < m; ++i)
{
scanf("%c %c", &a, &b);
getchar();
for (int j = 0; j < 26; ++j)
{
if (ch[j] == a)
ch[j] = b;
else if (ch[j] == b)
ch[j] = a;
}
}
for (int i = 0; i < len; i++)
{
printf("%c",ch[str[i]-'a']);
}
puts("");
return 0;
}
C. Median Smoothing
这题卡了我一个多小时,开始一直没想法,后来想到怎么做之后又因为敲太挫调了好久的bug,一发WA后干脆删掉重写,直到结束后15分钟才敲完orz.第二天交上去AC.
题意:
给定一个01串,每次操作后除首尾两个数字外所有数a[i]都变为(a[i-1]+a[i]+a[i+1])/2,问至少需要多少次操作才能使数字不再变化.输出操作次数及最终的结果.
例如对于01010有:
01010->00100->00000(不再变化)
共需要2次,最终结果为00000
解析:
多写几个之后可以发现,只有串中01交替的部分才会发生变化.比如:
原始串: 0 (0 1 0 1 0 1 0) 0 (0 1) 1 (1 0 1 0)
结果串: 0 (0 0 0 0 0 0 0) 0 (0 1) 1 (1 1 0 0)
实际上,01交替的子串的变化遵循以下规律:
- 若子串长度len为奇数,即首尾数字相同的,该子串变为同样长度,与首尾数字一致的串,如10101变为11111,而01010变为00000,需要的操作次数为len/2
- 若子串长度len为偶数,即首尾数字不同,子串中每个数字会变为与首尾数字中与其距离较近的一个,如101010变为111000,而01010101变为00001111,需要的操作次数为len/2-1
故而只要找出所有01交替的子串,将其修改,并取操作次数最大值即可.
(代码中对操作次数的统计写法是(len-2)/2+(len-2)%2,与上面的结论是等效的,或者干脆写成(len-1)/2)
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int bt[501000];
int ans[501000];
int main(int argc, char *argv[])
{
int n;
scanf("%d",&n);
int maxcnt = 0;
int pre = bt[0];
for (int i = 0; i < n; ++i)
{
scanf("%d",&bt[i]);
}
int d;
for (int i = 0; i < n; i++)
{
ans[i] = bt[i];
int j;
for (j = i; j < n-1; j++)
{
if (bt[j] == bt[j + 1])
break;
}
d = j - i - 1;
for (int k = i; k <= j; k++)
{
if (k - i < j - k)
ans[k] = bt[i];
else
ans[k] = bt[j];
}
if (maxcnt < d)
{
maxcnt = d;
}
i = j;
}
if (maxcnt < d)
{
maxcnt = d;
}
printf("%d\n",maxcnt/2+maxcnt%2);
for (int i = 0; i < n; ++i)
{
if (i != 0)
pu