牛客练习赛13-C题幸运数字III

转自一位大佬:http://blog.csdn.net/wyxeainn/article/details/79588812

题目:
链接:https://www.nowcoder.com/acm/contest/70/C
来源:牛客网

题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
假设现在有一个数字d,现在想在d上重复k次操作。
假设d有n位,用d1,d2,…,dn表示。
对于每次操作,我们想要找到最小的x (x < n),使得dx=4并且dx+1=7。
如果x为奇数,那么我们把dx和dx+1都变成4;
否则,如果x为偶数,我们把dx和dx+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。
输入描述:
第一行两个整数n,k表示d的长度和操作次数。
第二行一个数表示d。数据保证不存在前导零。
1 <= n <= 100,000
0 <= k <= 1000,000,000
输出描述:
一个数字表示答案。
示例1

输入
7 4
4727447

输出
4427477

示例2

输入
4 2
4478

输出
4478

解题思路:题目K很大,一次次的变换,对于题目给出的1秒时间显然是
不可能过的。则根据题目分析如下。
1.最早出现47的地方,如果47后面有7,则此时出现序列477,如果4是第
奇数个字符,则一次变换后,序列为447,再次出现47,4是第偶数个字符,
变换后变成477。由此可知,出现477(且其里面的47是串里面最左侧的47),
对于剩余变换次数,如果是奇数,最终中间位为4,否则不变,遇到这种情况
不论还有多少次变换,只要确定变换次数的奇偶即可确定答案。

2.最早出现47的地方,如果47前面有4,则此时出现序列447,如果47中的4
是第偶数位字符,则变换一次,序列变成477,则再次变换一次,序列变成447.
可以发现,出现447(且其里面的47是串里面最左侧的47),对于剩余变换次数,
是奇数次,则中间的4最终为7,否则不变。遇到这种情况不论还有多少次变换,
只要确定变换次数的奇偶即可确定答案。

3.不是1,2两种情况,只是单纯找到了47,如果4是第奇数个字符,则47 -> 44.
下一次考虑47就要从后一个4开始检测了。

4.如果4是第偶数个字符,则47->77,则检测位置需要从4左侧的位置开始。

5.当串中没有47的时候,无论还剩余多少次变换都是无用的,应立即结束。

代码如下:

#include <iostream>  
#include <stdio.h>  
#include <string>  

using namespace std;  

int n,k,temp;  
char str[1000000];  
int main() {  
    while(~scanf("%d%d",&n,&k)) {  
        scanf("%s",str);  
        //变换0次,直接输出。  
        if(k == 0) {  
           puts(str);  
        }  
        else {  
            for(int i = 0; i < n-1; i++) {  
                //遇到47组合。  
                if(str[i]=='4' && str[i+1]=='7') {  
                    //遇到477组合  
                    if(i+2<n && str[i+2]=='7') {  
                        temp = i+1;  
                        //4是第奇数个字符  
                        if(temp%2==1) {  
                            if(k%2==1) {  
                                str[i+1] = '4';  
                            }  
                            k = 0;  
                        }  
                    }  
                    if(!k) break;  
                    //遇到447的组合。  
                    if(i-1>=0 && str[i-1]=='4') {  
                        temp = i+1;  
                        //中间的4是第偶数个字符  
                        if(temp%2==0) {  
                            if(k%2) {  
                                str[i] = '7';  
                            }  
                            k = 0;  
                        }  
                    }  
                    if(!k) break;  
                    temp = i+1;  
                    //是第奇数个字符。  
                    if(temp%2) {  
                        str[i+1] = '4';  
                        k--;    //剩余变换次数-1  
                    }  
                    else {  
                        str[i] = '7';  
                        k--;  
                        i = i-2;  
                        /*i=i-2是因为,下次循环位置要从i-1开始,  
                        由于for循环中i会自增,所有让i减去2,再  
                        自增1,即下次循环从i-1开始。*/  
                    }  
                    if(!k) break;  
                }  
            }  
            puts(str);  
        }  
    }  
    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值