Codeforces Round #327 (div.2)(A B C D)

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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值