PTA 神奇字符串(双指针)

神奇字符串的定义为: 只含有1和2, 且将其按照连续的1和2拆开后,对应的每部分数字数量恰好和原字符串相同
例如: 1 22 11 2 1 22 1 22 11 2 11 22 ...... 每部分对应的1和2个数为
1 2 2 1 1 2 1 2 2 1 2 2 ...... 恰好等于原串
现给定N,求神奇串的前N位中有多少个1 .

输入格式:

第一行输入一个T,代表数据组数
接下来的T行,输入N
1 <= N <= 100000

输出格式:

对每一组输入,在一行中输出前N位中1的个数。

输入样例:

1
6

输出样例:

3

 解题思路:

此题其实只要把原数组推出来就很简单了,那么我们如何推呢?

一个数在数组中代表着两个意义,一个是对应的数值,一个是从前往后每个块(连续相同的数)中的数量,所以我们就可以使用双指针来写。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],c[N];
//a为原数组,c为原数组对应位置的值,但是代表块中的数的数量 

void intt(){
	memset(a,0,sizeof a);
	memset(c,0,sizeof c);
	int now=1,idx=1;//now为现在的填充值,idx为慢指针(跑块的数组) 
	for(int i=1;i<=N-5;i++){
		a[i]=c[i]=now;//同步更新 
		c[idx]--;//因为新加了一个值,所以慢指针对应的块所需的数量减少 1 
		if(c[idx]==0){//当 c[idx]==0 时,说明这个块已经完成了,那么我们就需要转换填充值了 
		//假设我们 now现在为 1,因为这个块我们都是用 1填充,所以如果后面还是 1,这个块中的数的数量就超额了
		//所以我们要把 1变成 2 
			if(now==1)now=2;
			else now=1;
			idx++;//寻找下一个块 
		}
	}
}

int main(){
	intt();//模拟原数组 
	int t;cin >> t;
	while(t--){
		int ans=0,n;
		cin >> n;
		for(int i=1;i<=n;i++){
			if(a[i]==1)ans++;
		}
		cout << ans << endl;
	}
	return 0;
} 

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值