A题:
题意:和题目一样,就是求第k小数。
思路:暴力肯定就sort了,不过数据太大,sort也过不了,那么根据快排,我们可以一次性砍掉一半左右的数据,只需要关心第k小数所在的数据范围就好了。后来才知道还有一个nth_element这个神奇的东西,会把第k个数直接放在k的位置。用法:nth_element(first,nth,last);我发现用这个的时候是把数据存放在a[0]-a[n-1]m排序输出k小数的时候输出的是a[k],也就是经过这个函数之后,数据k是放在a[k]位置,而不是a[k-1].下面是我的ac代码和用了element的代码。
1:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=5e6+5;
const LL mod=1e9+7;
inline int read() {
    char ch=getchar();int x=0,f=1;
    while(ch<'0' || ch>'9')   {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[maxn];
int c[maxn];
int find(int r,int k) {
    if(r==1) {
        return a[r];
    }
    int low=1,high=r;
    int num=a[1];
    for(int i=2;i<=r;++i) {
        if(a[i]<=num) {
            c[low++]=a[i];
        }
        else {
            c[high--]=a[i];
        }
    }
    if(low==k) return num;
    else if(low<k) {
        for(int i=low+1;i<=r;++i) {
            a[i-low]=c[i];
        }
        return find(r-low,k-low);
    }
    else {
        for(int i=1;i<low;++i) {
            a[i]=c[i];
        }
        return find(low-1,k);
    }
}
void solve() {
    int n,k;
    n=read();
    k=read();
    for(int i=1;i<=n;++i) {
        a[i]=read();
    }
    cout<<find(n,k)<<"\n";
}
int main() {
//  cout<<"Accepted!\n";
    int t;
    cin>>t;
        while(t--) {
            solve();
        }
    return 0;
}

2:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=5e6+100;
const LL mod=1e9+7;
int read() {
    char ch=getchar();int x=0,f=1;
    while(ch<'0' || ch>'9')   {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[maxn];
int main() {
//  cout<<"Accepted!\n";
    int t;
    cin>>t;
        while(t--) {
            int n,k;
            n=read();
            k=read();
            for(int i=0;i<n;++i) {
                a[i]=read();
            }
//            cout<<k<<"\n";
            nth_element(a,a+k,a+n); 
            cout<<a[k]<<"\n";
        }

    return 0;
}

B题:
题意:给n个点,问最多选出多少条直线不能平行也不重合。
思路:我刚开始以为一个点用过就不能用了,后来才知道可以重复使用。既然这样那就直接暴力检查任意两条直线就好了,那样就O(图片说明 ),我们稍微优化一下,运用set的性质,我们把一条直线的斜率放进去就很好的去除了重合和平行,那么还有一个精度问题,我们就不直接使用斜率,而是用分母分子这样一组数来表示,同时我们规定分母一定为正。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const LL mod=1e9+7;
int read() {
    char ch=getchar();int x=0,f=1;
    while(ch<'0' || ch>'9')    {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int gcd_(int a,int b) {return b==0?a:gcd_(b,a%b);}
LL fpow(LL a,LL b) {
    LL res=1;
    while(b) {
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res;
}
int a[205],b[205];
set<pair<int,int> > se;
int main() {
//    cout<<"Accepted!\n"
    int n;
    cin>>n;
    for(int i=1;i<=n;++i) {
        cin>>a[i]>>b[i];
    }
    int flag=0;
    for(int i=1;i<n;++i) {
        for(int j=i+1;j<=n;++j) {
            if(b[i]==b[j] ) {
                flag=1;
                continue;
            }
            int X=a[i]-a[j],Y=b[i]-b[j];
            if(X<0) X=-X,Y=-Y;
            int Z=gcd_(X,Y);
            X/=Z;
            Y/=Z;
            se.insert(make_pair(X,Y));
        }
    }
    cout<<se.size()+flag;
    return 0;
}

C题:
题意:这个没啥可说的。
思路:不过给的样例数据多了3,,,。直接三分就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int a[maxn];
int s[maxn];
int dis(int x,int y) {
    if(x==y) return 0;
    return min(abs(s[x]-s[y]),a[1]-abs(s[x]-s[y]));
}
int main() {
//    cout<<"Accepted!\n";
    int n;
    cin>>n;
    for(int i=2;i<=n;++i) {
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    cin>>a[1];
    a[1]+=s[n];
    int ans=0;
    for(int i=1;i<=n;++i) {
        int l=1,r=n;
        while(l+1<r) {
            int m1=(l+r)>>1,m2=(m1+r)>>1;
            if(dis(m1,i)>dis(m2,i)) {
                r=m2;
            }
            else l=m1;
        }
        ans=max(ans,dis(l,i));
    }
    cout<<ans;
    return 0;
}

D题:
题意:给一组问的数据和回答,让你找一个数,使这些回答尽量多的正确。
思路:离散化加差分,最后前缀和找最大就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
set<int> se;
map<int,int> mp;
int main() {
//    cout<<"Accepted!\n";
    int n;
    cin>>n;
    int x;
    char c;
    int res=0,s=0,inf=1e17;
    while(n--) {
        scanf("%d %c",&x,&c);
        if(c=='.') {
            se.insert(x);
            mp[x]++;
            se.insert(x+1);
            mp[x+1]--;
        }
        else if(c=='+') {
            se.insert(-inf);
            mp[-inf]++;
            se.insert(x);
            mp[x]--;
        }
        else {
            se.insert(x+1);
            mp[x+1]++;
        }
    }
    for(set<int>::iterator it=se.begin();it!=se.end();it++) {
//        cout<<*it<<' '<<mp[*it]<<"\n";
        s+=mp[*it];
        res=max(res,s);
    }
    cout<<res;
    return 0;
}

E题:
题意任意交换两个孩子的位置,让他们从小到大排好序的交换次数。
思路:刚开始以为快排找交换次数,后来发现这是错的。然后我就想直接从第一个孩子开始排,直接把他放到所需的位置,就这样排一遍记录次数。写完提交发现这样是对的。后来通过群友巨巨们了解到,这就是找环的个数,仔细想想就是这样。一个环内所有的人要放到指定位置就是减缓环内元素-1次,那我们也不用记录环内元素个数,就直接记录环的个数,然后减去环的个数就好了。下面是我的ac代码。

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int b[maxn];
map<int,int> mp;
int main() {
    int n;
    cin>>n;
    for(int i=1;i<=n;++i) {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    for(int i=1;i<=n;++i) {
        mp[b[i]]=i;
    }
    int res=0,pos=1;
    while(pos<n) {
        if(mp[a[pos]]!=pos) {
            int i=mp[a[pos]],temp=a[pos];
            a[pos]=a[i];
            a[i]=temp;
            res++;
        }
        else {
            pos++;
        }
    }
    cout<<res<<"\n";
}