USACO 2011 November Cow Lineup /// map set 尺取法 oj25279
题目大意:
输入n 接下来n行描述n头牛的编号num和品种id
得到包含所有id的最短段 输出最短段的编号差
Sample Input
6
25 7
26 1
15 1
22 3
20 1
30 1
Sample Output
4
Hint
INPUT DETAILS:
There are 6 cows, at positions 25,26,15,22,20,30, with respective breed IDs 7,1,1,3,1,1.
OUTPUT DETAILS:
The range from x=22 up through x=26 (of total size 4) contains each of the distinct breed IDs 1, 3, and 7 represented in FJ's herd.
有思路而不会代码实现也是够痛苦
将牛按num排序后
15 20 22 25 26 30
1 1 3 7 1 1
将15为段头 直到段尾为25时符合要求出现了所有id
但 id 1 出现过两次 所以可以缩小该段 将段头移向下一位20
此时为符合要求的最小段 保存当前段的编号差
将段头移向下一位 继续移动段尾
直到符合要求进行判断 更新保存最小的编号差
#include <bits/stdc++.h> using namespace std; struct Cow{ int num,id; }cow[50005]; map <int,int> m; /// 记录id出现的次数 set <int> id_set; /// 记录出现过的品种id 得到一共有多少种品种 bool cmp(Cow q,Cow p) { return q.num<p.num; } /// 结构体按编号num排序 不会重复所以不需考虑相等 int main() { /// num_map为符合要求的一段的该段当前id数 /// num_id为该队中的所有id数 /// head tail为当前该段的段头和段尾 int n,num_id,num_map,head,tail,mini; while(~scanf("%d",&n)) { id_set.clear(); m.clear(); for(int i=0;i<n;i++) { scanf("%d%d",&cow[i].num,&cow[i].id); m[cow[i].id]=0; id_set.insert(cow[i].id); } sort(cow,cow+n,cmp); num_id=id_set.size(); /// set可以去重 即所有id数 head=tail=num_map=0; mini=0x3f3f3f3f; // for(int i=1;i<=n;i++) // printf("%d %d\n",cow[i].num,cow[i].id); // printf("\n"); while(1) { while(num_map!=num_id && tail<n) { if(m[cow[tail].id]==0) num_map++; m[cow[tail++].id]++; /// 如果此id没出现过则该段当前id数+1 /// m记录该段id出现次数 } /// 持续记录id,直到该段当前id数为所有id数 或 已到队尾 if(tail==n && num_map!=num_id) break; /// 已到队尾 且 不存在符合要求的组合 则跳出 while(m[cow[head].id ]>1) m[cow[head++].id ]--; /// 当前id数 为 所有id数 若段头的id在该段中出现次数>1 /// 则可缩小该段长度 段头可移到下一位 /// 如 13312 这种情况可缩小该段长度到 312 mini=min(mini,cow[tail-1].num-cow[head].num); m[cow[head++].id]--; num_map--; /// 继续遍历后面有无符合要求的组合 /// 段头移到下一位 该段中当前id数-1 } printf("%d\n",mini); } return 0; } /* 6 25 7 26 1 15 1 22 3 20 1 30 1 */
...原来这是尺取法
再加种写法 ...虽然差不多
while(head<=tail&&tail<=n) { if(num_map<num_id) { if(m[cow[tail].id]==0) num_map++; m[cow[tail++].id]++; } else if(num_map==num_id) { while(m[cow[head].id]>1) m[cow[head++].id]--; mini=min(mini,cow[tail-1].num-cow[head].num); m[cow[head++].id]--; num_map--; } }