双指针,尺取法

一,字符串
题目大意:链接:https://ac.nowcoder.com/acm/contest/20960/1027
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
思路:用两个for循环枚举子串的左端点和右端点,如果直接暴力枚举的话,时间复杂度就会到O(n^12)肯定会超时,但是其实不用两个for循环。当区间内刚好包含26个字母的时候,左端点向前移动一个,右端点不动,此时区间内的字母总数肯定是小于等于26的,此时判断区间是否满足条件并且计算区间的长度,如果长度比初始的小就更新答案。
上代码:
#include<bits/stdc++.h>
using namespace std;
int a[30]={0};
bool check()
{
	for(int i=0;i<=25;i++)
	{
		if(a[i]==0) return 0;
	}
	return 1;
}
int main()
{
	string s;
	cin >> s;
	int len=s.length();
	int ans=len;
	int r=0;
	for(int l=0;l<len;l++)
	{
		while(r<len&&!check())
		{
			a[s[r]-'a']++;
			r++;
		}
		if(check()) ans=min(ans,r-l);
		a[s[l]-'a']--;
	}
	cout << ans << endl;
	return 0;
}
二.丢手绢
题目大意:链接:https://ac.nowcoder.com/acm/contest/20960/1030
第一行一个整数N,表示有N个小朋友玩丢手绢的游戏。
接下来的第2到第n行,第i行有一个整数,表示第i-1个小朋友顺时针到第i个小朋友的距离。
最后一行是第N个小朋友顺时针到第一个小朋友的距离。
注意事项:因为要用到约瑟夫环,所以n个小朋友的话第一个小朋友编号是0;
#include<bits/stdc++.h>
using namespace std;
int a[300];

int main()
{
	int sum=0;
	int n,a[100010];
	cin >> n;
	for(int i=0;i<=n;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	int r=0,dist=0;
	int ans=0;
	for(int l=0;l<=n;l++)
	{
		while(ans<sum/2)
		{
			ans+=a[r%n];
			r++;
		}
         dist=max(dist,min(ans,sum-ans));
		 ans-=a[l];
	}
	cout << dist << endl;
	return 0;
}


全部评论

相关推荐

舂锋:不能投什么岗都用一份简历,一般都是要看企业的岗位需求来写职业技能或者是项目经历,跟岗位相关的就写多一点。
点赞 评论 收藏
分享
07-08 13:48
门头沟学院 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务