暑假集训7月18日

E - Dist Max 2

最小值的最大值,这种题目一般都是二分

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10,inf=0x3f3f3f3f;
struct node
{
    int x,y;
}a[N];
int n;
bool cmp(node a,node b)
{
    if (a.x!=b.x)return a.x<b.x;
    else return a.y<b.y;
}
bool check(int mid)
{
    int l=1;
    int mi=inf,ma=0;
    for (int i=1;i<=n;i++)
    {
        while (l<=n&&abs(a[i].x-a[l].x)>=mid)
        {
            mi=min(mi,a[l].y),ma=max(ma,a[l++].y);
        }
        if (a[i].y-mi>=mid||ma-a[i].y>=mid)
            return true;
    }
    return false;
}
signed main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        cin>>a[i].x>>a[i].y;
    sort(a+1,a+n+1,cmp);
    int l=0,r=inf;
    while (l<r)
    {
        int mid=(l+r+1)>>1;
        if (check(mid))l=mid;
        else r=mid-1;
    }
    printf("%d\n",l);
    return 0;
}

 

 check函数就是要判断是否有两个点满足m i n ( x i − x j , y i − y j ) > = m i d ,因为要找的是最小的最大值,就要尽可能往右找,min>=mid说明答案在右边,所以mid的取值要往右,l=mid,前面小的就不满足,区间就往右边缩。

要找两个点,先固定i点,然后去找j点。枚举i点的时候,对每一个i点枚举j点。因为只有xi-xj>=mid的时候,才需要考虑m i n ( x i − x j , y i − y j ) 有没有可能在y的时候会被更新到更小,while循环枚举j,在满足m i n ( x i − x j , y i − y j ) > = m i d的条件下,找到最大的和最小的y值,然后分别计算他们与此时的i点的y值的差,while 循环结束的时候满足m i n ( x i − x j , y i − y j ) > = m i d的y的两个最大的差值就找到了,然后看这两个差中有没有哪一个是比mid大,如果大,说明答案还在右边,这个时候返回true,继续把区间往右缩,反之答案在左边,就是往左缩区间,最后l==r的时候,l就是要找的答案。

B - One More aab aba baa

 和全排列一样,但是会有重复的情况出现,所以要去重。用set去重,貌似它是会自己从小到大排。

#include <iostream>
#include <math.h>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <set>

using namespace std;
const int N = 5e5+10;

int idx;
char fa[10];
string a[N],aa;
set<string> q;
int x, len, vis[10],n;
char s[10];

void dfs(int u)
{
    if(u==len)
    {
        aa= "";
        for(int i=0; i<len; i++)
        {
            aa += fa[i];
        }
        q.insert(aa);
        return ;
    }
    for(int i = 0; i<len; i++)
    {
        if(!vis[i])
        {
            fa[u] = s[i];
            vis[i] = 1;
            dfs(u+1);
            vis[i] = 0;
        }
    }
}

int main()
{
    char ch;
    scanf("%s %d",s,&n);
    len = strlen(s);
    dfs(0);
    int x= 0;
    for(auto item: q)
    {
        x++;
        if(x==n)
            cout<<item<<endl;
    }
    return 0;
}

 

C - Coprime 2

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N],prime[N];
bool st[N];
int n,m,cnt,k;
void div(int x)
{
    for (int i=2; i<=x/i; i++)
    {
        if (x%i==0)
        {
            int s=0;
            while (x%i==0)
            {
                x/=i;
                s++;
            }
            if (i>1)
            {
                st[i]=1;
            }
            if (s>1)
            {
                st[s]=1;
            }
        }
    }
    if (x>1)
    {
        st[x]=1;
    }
}
void judge()
{
    for (int i=2; i<=m; i++)//筛掉因数的倍数
    {
        if (st[i])
        {
            k++;
            int j=i;
            while (j<=m)
            {
                st[j]=true;
                j+=i;
            }
        }
    }
}
signed main()
{
    scanf("%d%d",&n,&m);
    for (int i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
        div(a[i]);
    }
    judge();
    printf("%d\n",m-k);
    for (int i=1; i<=m; i++)
        if (!st[i])printf("%d\n",i);
    return 0;
}

 

posted @ 2022-07-18 20:56  好腻友Π  阅读(35)  评论(0)    收藏  举报