poj3061
尺取法裸题,维护动态数组即可 ,l,r,sum,ans;
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100005
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
LL a[100010];
int n, t, ans = INF;
LL sum, s;
int main()
{
scanf("%d", &t);
while (t--){
scanf("%d %I64d", &n, &s);
for (int i = 0; i < n; i++) scanf("%I64d", a+i);
int l = 0, r = 0;
ans = INF; sum = 0;
while (1){
while (r<n && sum<s) sum += a[r++];
if (sum < s) break;
ans = min(ans, r-l);
sum -= a[l++];
}
if (ans == INF) ans = 0;
printf("%d
", ans);
}
return 0;
}
poj3320:
这个题理解题意有点难,
主要就是说,找一段连续区间让此区间覆盖所有的不同的a[i];
(map+set+尺取)
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> #include <map> #include <set> typedef long long LL; using namespace std; const int inf=0x3f3f3f; const int maxn = 1000010; int a[maxn]; map<int ,int> mp; set<int> s; int main() { int n; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); s.insert(a[i]); } int m=s.size(); int l=0,r=0,ans=inf,sum=0; while(1) { while(r<n&&sum<m) { if(mp[a[r++]]++==0) sum++; } //cout<<sum<<" "<<r<<endl; //for(map<int,int>::iterator it=mp.begin(); it!=mp.end(); it++) //cout<<it->first<<" "<<it->second<<endl; if(sum<m) break; ans=min(ans,r-l); if(--mp[a[l++]]==0) sum--; } printf("%d ",ans); return 0;
}
codeforces 616 d(E5)(尺取法+set)map也可以
找不同数字不超过k个的最长连续区间,双指针维护;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int n,k;
int a[maxn],f[maxn];
set<int> s;
int main()
{
cin>>n>>k;
for(int i=1; i<=n; i++)
cin>>a[i];
int ans=0,ansl,ansr,l=1,r=0;
int mx=0;
while(l<=n&&r<=n)
{
if(s.size()<=k)
{
if(mx<r-l+1)
{
mx=r-l+1;
ansl=l;
ansr=r;
}
}
if(s.size()>k)
{
while(s.size()>k)
{
f[a[l]]--;
if(f[a[l]]<=0)
{
s.erase(a[l]);
}
l++;
}
}
else
{
f[a[++r]]++;//必须是++r,如果r++,更新区间时会出错;
s.insert(a[r]);
}
}
printf("%d %d",ansl,ansr);
}
map版本:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int n,k;
int a[maxn],f[maxn];
map<int,int> mp;
int main()
{
cin>>n>>k;
for(int i=1; i<=n; i++)
cin>>a[i];
int ans=0,ansl,ansr,l=1,r=0;
int mx=0;
while(l<=n&&r<=n)
{
if(mp.size()<=k)
{
if(mx<r-l+1)
{
mx=r-l+1;
ansl=l;
ansr=r;
}
}
if(mp.size()>k)
{
while(mp.size()>k)
{
mp[a[l]]--;
if(mp[a[l]]<=0)
{
mp.erase(a[l]);
}
l++;
}
}
else
{
mp[a[++r]]++;
//mp.insert(a[r]);
}
}
printf("%d %d",ansl,ansr);
}