1. 程式人生 > >二分+尺取總結及練習題講解

二分+尺取總結及練習題講解

尺取:

理解了尺取後用題目來做練習,實際問題中尺取的條件多種多樣,要多做練習多總結。

訓練題中的B題

#include <bits/stdc++.h>
using namespace std;

char str[100000+10];
int vis[200];
int main()
{
	int n;
        set<char> s;

	while( ~scanf("%d", &n ) )
	{
		int kind = 0;			//num記錄不同的元素出現的總個數
		scanf("%s", str );
		s.clear();
		for( int i=0; i<n; i++ )
                   s.insert( str[i] );
                kind = s.size();

		memset( vis, 0, sizeof(vis) );				//先清0
		int ans = int(1e9);
		int left = 0;					//記錄起點,開始在 0
		int cnt = 0;
		for( int i=0; i<n; i++ )
		{
			if( !vis[str[i]] )		//cnt記錄不同字母出現的次數,即cnt記錄的是已經出現的種類
				cnt ++;
			vis[ str[i] ]++;		//每個字母出現次數+1
			if( cnt == kind )
			{
				while( cnt == kind )
				{
					ans = min( ans, i - left +1 );
					if( vis[str[left]] == 1 )		// left 起點的型別,直到 i 終點也只出現一次,再向後移動cnt != kind,退出迴圈
						cnt--;
					vis[str[left]]--;			//起點出現次數先-1,再右移
					left++;
				}
			}
		}
		printf("%d\n", ans );
	}

	return 0;
}