清北刷题冲刺 10-31 a.m

集合

 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[1000010],cnt;
int main(){
    freopen("multiset.in","r",stdin);freopen("multiset.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    if(n==1&&a[1]==0){
        puts("0");
        return 0;
    }
    int ans=0;
    sort(a+1,a+n+1);
    int q=1;
    for(int i=1;i<=n;i++){
        if(a[i]!=0){q=i;break;}
        cnt++;
    }
    while(1){
        if(q>n)break;
        ans++;cnt=cnt/2+cnt%2;
        for(int i=q;i<=n;i++)a[i]-=1;
//        for(int i=1;i<=n;i++)cout<<a[i]<<' ';
        while(a[q]==0&&q<=n)cnt++,q++;
    }
    while(cnt>1){
        ans++;
        cnt=cnt/2+cnt%2;
    }
    printf("%d",ans);
}
50分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000010
using namespace std;
int n,a[maxn],cnt[maxn],res,lim;
int main(){
    freopen("multiset.in","r",stdin);
    freopen("multiset.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        lim=max(lim,a[i]);
        cnt[a[i]]++;
    }
    int l=0,z=cnt[0];
    for(int i=1;i<=lim;i++){
        res++;
        z=(z+1)/2;
        z+=cnt[i];
    }
    for(;z>1;z=(z+1)/2)res++;
    printf("%d",res);
    return 0;
}
100分

 

 

道路分组

 

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define maxn 100010
#define maxm 500010
using namespace std;
int n,m,num,head[maxn],mid;
int q[maxm],q1[maxm],cnt;
vector<int>road[500010];
struct node{
    int to,pre,id;
}e[maxm];
struct Node{
    int l,r;
}jian[maxm];
void Insert(int from,int to){
    e[++num].to=to;
    e[num].id=num;
    e[num].pre=head[from];
    head[from]=num;
}
bool vis[maxm];
void dfs(int pos,int c){
    if(pos==n){
        cnt++;
        jian[cnt].l=0x7fffffff;
        for(int i=1;i<c;i++){
            road[cnt].push_back(q[i]);
            jian[cnt].l=min(jian[cnt].l,q[i]);
            jian[cnt].r=max(jian[cnt].r,q[i]);
        }
        return;
    }
    for(int i=head[pos];i;i=e[i].pre){
        int to=e[i].to;
        if(!vis[to]){
            q[c]=i;
            vis[to]=1;
            dfs(to,c+1);
            vis[to]=0;
        }
    }
}
bool cmp(Node x,Node y){return x.l<y.l;}
int main(){
    freopen("road.in","r",stdin);freopen("road.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        Insert(x,y);
    }
    vis[1]=1;
    dfs(1,1);
    memset(vis,0,sizeof(vis));
    sort(jian+1,jian+cnt+1,cmp);
    int ans=1;
    int L=0,R=0x7fffffff;
    int last=0;
    for(int i=1;i<=cnt;i++){
        L=max(L,jian[i].l);
        R=min(R,jian[i].r);
        if(L>=R){
//            if(!flag)flag=1,ans+=2;
//            else ans+=1;
            ans+=2;
            L=0;R=0x7fffffff;
            last=i;
        }
    }
    if(last!=cnt)ans++;
    printf("%d",ans);
    return 0;
}
20分 暴力
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define maxn 500010
using namespace std;
int n,m,vis[maxn],x[maxn],y[maxn];
vector<int>vec[maxn];
bool dfs(int u){
    if(vis[u])return false;
    if(u==n)return true;
    vis[u]=1;
    bool ret=false;
    for(int i=0;i<vec[u].size();i++){
        ret=dfs(vec[u][i]);
        if(ret)return true;
    }
    return false;
}
bool check(int sta,int las){//检验sta~las的边能(0)否(1)在同一组内 
    for(int i=sta;i<=las;i++)
        vec[x[i]].push_back(y[i]);
    bool ret=dfs(1);
    for(int i=sta;i<=las;i++){
        vis[x[i]]=vis[y[i]]=0;
        vec[x[i]].clear();
    }
    vis[1]=0;
    return ret;
}
int main(){
    freopen("road.in","r",stdin);freopen("road.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d%d",&x[i],&y[i]);
    int now=0,ans=0;
    while(now<m){
        int i;
        for(i=1;i+now<=m;i<<=1)
            if(check(now,now+i-1))break;
        i>>=1;
        int nowtmp=now+i;
        for(;i>0;i>>=1)
            if(nowtmp+i<=m&&!check(now,nowtmp+i-1))
                nowtmp+=i;
        ans++;now=nowtmp;
    }
    cout<<ans;
}
100分 二分

 

 

 

补兵

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 1010
using namespace std;
int T,n,a[maxn];
int main(){
    freopen("cs.in","r",stdin);freopen("cs.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        int p=1,ans=0;
        while(1){
            if(a[p]==2&&p!=n){
                a[p+1]-=2;
                a[p]-=1;
                for(int i=p+2;i<=n;i++)a[i]-=1;
                sort(a+1,a+n+1);
            }
            else{
                a[p]-=2;
                if(a[p]==-1)ans++;
                for(int i=p+1;i<=n;i++)a[i]-=1;
            }
            while(a[p]<=0)p+=1;
            if(p>n)break;
        }
        printf("%d\n",ans);
    }
}
0分 贪心
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1010
using namespace std;
int a[maxn],cnt[maxn],sta[maxn],c[maxn],f[maxn][maxn];
int main(){
    freopen("cs.in","r",stdin);freopen("cs.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--){
        int n,mxn=0;
        scanf("%d",&n);
        memset(cnt,0,sizeof(cnt));
        memset(c,0,sizeof(c));
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            ++cnt[a[i]];
            mxn=max(mxn,a[i]);
        }
        int top=0;
        for(int i=1;i<=mxn;i++)
            if(cnt[i]==0)sta[++top]=i;
            else{
                while(cnt[i]>1&&top>0){
                    c[sta[top--]]=i;
                    --cnt[i];
                }
                c[i]=i;
            }
        int ans=0;
        for(int i=1;i<=mxn;i++){
            for(int j=0;j<=i;j++){
                if(j>0)f[i][j]=f[i-1][j-1];
                if(c[i]!=0&&j+c[i]-i<i)
                    f[i][j]=max(f[i][j],f[i-1][j+c[i]-i]+1);
                ans=max(ans,f[i][j]);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
100分 dp

 

 

 

预计得分0+30+玄学
实际得分50+20+0
今天上午的题风格很奇怪,感觉暴力很难打,T1一开始没有思路,后来瞎几把乱打得了50。T2写了非常裸的暴力,T3没有思路,就贪心写了写。
这套题比较锻炼暴力能力,对思维的挑战也比较大,但是T2暴力得的分有点少,改题的时候要看看暴力怎么优化
小结

 

posted @ 2017-10-31 09:46  Echo宝贝儿  阅读(273)  评论(2编辑  收藏  举报