算法题番外篇之天弃娇子、刷墙、胜者为王

1、题目:小明预进行一场闯关小游戏,一共有n关,每关游戏有a[i]个按钮,其中只有1个是正确按钮且的正确按钮位置是不变(可以记忆,)

按到正确按钮继续闯关,按到错误按钮重新返回第一关开始

求:小明闯关成功最多需要按按钮的次数。

例:输入[2,2,2]输出9

public long findMaxButtons(int[] a){
    long res=a.length;//
    for(int i=0;i<a.length;i++){
        //第i关要失败a[i]-1次,每次都要按i次按钮
        res+=(long)(a[i]-1)(i+1);
    }
    return long;

}

2、刷墙

最近小明搬到了新家,正在粉刷墙壁,不幸的是他粉刷的墙壁并不理想,它的墙壁是一个长度为n的格子,

每个格子用0表示红色,用1表示蓝色,现在墙壁是一个非常混乱的颜色,他想将墙壁左边涂成全是蓝色

右边全是红色,可以将墙壁刷成全是红色或蓝色,请问他至少需要粉刷多少个格子墙壁成为他需要的样子。

输入描述:

第一行一个整数n(1<=n<=100000)

第二行长度为n的01串,0表示红色,1表示蓝色

输出:

一个整数表示最少粉刷次数。

解析:一个长度为n的字符01组成的字符串,要把串变成某个位置及其左边全是1,右边全是0至少修改多少个字符。

1 0 1 0 1 0 1 0
1 1 1 0 0 0 0 0

把[1,i]这个区间内的数全变为1的次数等于这个区间0的个数

把[i+1,n]这个区间内的数全变为0的次数等于这个区间1的个数

可以预处理前缀和sum[i]为[1,i]中1的个数

然后可以在o(1)时间复杂度内求出每个分界点要变化的数的个数,更新答案即可。

前缀和:

在经过一次O(n)的预处理后,可以O(1)查询区间和

sum[i]=sum[i-1]+a[i]

  和: sum  1     3     6     10   15

 数据:a     1     2     3      4     5       6     7       8   

下标: 0     1     2     3      4     5       6     7       8

sum[i]表示下标为[1,n]的权值和

[l,r]  sum[r]-sum[l-1]

char s[N];
int  sum[N];
int main()
{

    int n;
    scanf("%d%%s",&n,s+1);
    for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+s[i]-'0';
    int res=n;
    for(int i=0;i<=n;i++){
        //[1,i]中'0'的个数为i-sum[i]
        //[i+1,n]中'1'的个数为sum[n]-sum[i]
        res=min(res,i-sum[i]+sum[n]-sum[i]);
    }
    printf("%d\n",res);
    return 0;
}

3、 胜者为王

小赵、小钱、小孙三人正在进行一个游戏,游戏中有n个回合,每个人都有一个字符串,三人的字符串长度相等,

每个回合它们必须要改字符串中的一个字母,最后每个人的分数是自己字符串中出现字符最多的字母的分数,

分数最高者获胜,输出获胜者的名字,若有两人或以上相同分数输出draw

输入:

7

treasurehunt

threefriends

hicodeforces

输出:

xiao wang 

一行一个字符串,表示游戏结束。

解析:

对于每个人来说有一个显而易见的贪心策略,就是先找出出现次数最多的字母是哪个,然后把其他字母

尽可能都改成这个字母

设出现次数最多的字母数量是x,在进行n回合,这个字母可以是min(x+n,len)个;

char a[N],b[N],c[N];
int cnt[256];
int main()
{
    int n;
    scanf("%d%s%s%s",&n,a,b,c);
    int x=0,y=0,z=0;
    for(int i=0;a[i];i++)x=max(x,++cnt(a[i]));
    memset(cnt,0,sizeof(cnt));
    for(int i=0;b[i];i++)x=max(x,++cnt(b[i]));
    memset(cnt,0,sizeof(cnt));
    for(int i=0;c[i];i++)x=max(x,++cnt(c[i]));
    //memset(cnt,0,sizeof(cnt));
    int len=strlen(a);
    x=min(x+n,len);
    y=min(y+n,len);
    z=min(z+n,len);
    if(x>yandx>z) puts("xiaoming");
    else if(y>xandy>z) puts("xiaowang");
    else if(z>x and z>y) puts("xiaoli");
    else puts("draw");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/l641208111/article/details/114999141
今日推荐