取尺法专题

链接:https://ac.nowcoder.com/acm/contest/3002/G
来源:牛客网

eli拿到了一个仅由小写字母组成的字符串。
她想截取一段连续子串,这个子串包含至少  个相同的某个字母
她想知道,子串的长度最小值是多少?
注:所谓连续子串,指字符串删除头部和尾部的部分字符(也可以不删除)剩下的字符串。例如:对于字符串arcaea”而言,arc”、rcae”都是其子串。而“car”、aa”则不是它的子串。

#define Inf 0x3f3f3f3f
#define maxn 250015
#define ll long long
#define PI acos(-1.0)
#define lowbit(x) (x&-x)
#define P pair<ll, pair<ll, ll> >
#define EPS 1e-8
const int N = 2005;
int n, m, k, len, ans, cost;
char str[maxn];
map<char, int>mp;
int main(){
    while(~scanf("%d%d", &n, &k)){
        scanf("%s", str);
        mp.clear();
        int l = 0, r = 0;
        int res = Inf;
        while(1){
            while(r < n && mp[str[r]] < k){ //mp记录每个字符出现的次数,直到k
                mp[str[++r]] ++;
            }
            if(r >= n && mp[str[r]] < k){ //若右端点到达终点则退出
                break;
            }
            res = min(res, r-l); //记录最短长度
            mp[str[l++]] --; //压缩长度
        }
        if(res != Inf)
            printf("%d\n", res+1);
        else
            printf("-1\n");
    }
    return 0;
}
View Code
链接:https://ac.nowcoder.com/acm/contest/3002/C
来源:牛客网

umi对弓道非常痴迷。
有一天,她在研究一个射箭问题:
在一个无限大的平面中,她站在  这个坐标。
  个靶子,第  个靶子的坐标是 
umi准备在  轴或  轴上放置一块挡板来挡住弓箭的轨迹,使得她可以射中的靶子数量不超过  个。
她想知道挡板的最短长度是多少?
注:假定弓箭的轨迹是起点为umi坐标、长度无穷大的射线。umi和靶子的体积可以无视。挡板的边缘碰到弓箭轨迹也可视为挡住弓箭。
注2:挡板不能弯折,起始和终点必须在同一坐标轴上。

首先确定umi所在位置的象限。很明显同一象限的点是不可能用挡板挡掉的,对于剩下的点找出线段和 xx 轴或 yy 轴的交点,统计坐标位置(如果存在交点的话)。
之后双指针维护 xx 轴上或者 yy 轴挡住 n-k个点的挡板长度最小值。注意 x 轴和 y 轴要分开计算。
 
double xx, yy, x, y;
vector<double>v1, v2;
int main(){
    scanf("%lf%lf%d%d", &xx, &yy, &n, &k);
    v1.clear(), v2.clear();
    for(int i = 0; i < n; i ++){
        scanf("%lf%lf", &x, &y);
        if(x*xx < 0){
            v2.push_back(yy-xx*(y-yy)/(x-xx)); //计算线段与轴交点
        }
        if(y*yy < 0){
            v1.push_back(xx-yy*(x-xx)/(y-yy)); //与轴交点
        }
    }
    k = n-k; //处理剩下的n-k个点即可
    double res = Inf;
    if(v1.size() >= k){
        int i = 0, j = k-1; //以n-k为长度移动
        sort(v1.begin(), v1.end());
        while(j < v1.size()){
            res = min(res, v1[j++]-v1[i++]);
        }
    }
    if(v2.size() >= k){
        int i = 0, j = k-1;
        sort(v2.begin(), v2.end());
        while(j < v2.size()){
            res = min(res, v2[j++]-v2[i++]);
        }
    }
    if(res < Inf)
        printf("%.8lf\n", res);
    else
        printf("-1\n");
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/microcodes/p/12319300.html