扩大
缩小

提高组模拟题 20180905

一场咕咕咕咕的模拟测试

这里写图片描述

Problem A:绩效等级

solution:暴力!
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
const int N=10010;
int t,n,tot;
 
struct data{
    int cnt,id;
    bool operator < (const data &b) const {
        if(cnt==b.cnt)return id<b.id;
        return cnt>b.cnt;
    }
}cnt[100001];
 
int main(){
    scanf("%d",&t);
    for(int k=1;k<=t;k++){
        for(int i=1;i<=N;i++){
            cnt[i].cnt=cnt[i].id=0;
        }
        tot=0;
        scanf("%d",&n);
        if(n==0){
            printf("Case #%d:\n",k);
            puts("Bad Mushroom");
            continue;
        }
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            x=10000-(100-x)*(100-x);
            if(!cnt[x].cnt)tot++,cnt[x].id=x;
            cnt[x].cnt++;
        }
        sort(cnt+1,cnt+N+1);
        printf("Case #%d:\n",k);
        if(cnt[1].cnt==cnt[tot].cnt and n!=1){
            puts("Bad Mushroom");
            continue;
        }
        int last=cnt[1].cnt;
        printf("%d ",cnt[1].id);
        for(int i=2;i<=tot;i++){
            if(cnt[i].cnt==last){
                printf("%d ",cnt[i].id);
            }
        }
        puts("");
    }
    return 0;
}

Problem B:舞会配对

solution:排序!暴力!
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
 
using namespace std;
 
vector<int> bt,bs,gt,gs;
int n,ans;
 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        if(x>0){
            bt.push_back(x);
        }else bs.push_back(-x);
    }
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        if(x>0){
            gt.push_back(x);
        }else gs.push_back(-x);
    }
    sort(gt.begin(),gt.end());
    sort(bt.begin(),bt.end());
    sort(gs.begin(),gs.end());
    sort(bs.begin(),bs.end());
    for(int i=0,j=0;i<bs.size() and j<gt.size();i++){
        if(bs[i]>gt[j]){
            ans++;
            j++;
        }
    }
    for(int i=bt.size()-1,j=gs.size()-1;~i and ~j;i--){
        if(bt[i]<gs[j]){
            ans++;
            j--;
        }
    }
    printf("%d\n",ans);
    return 0;
}

Problem C:平衡的子集

solution:显然我们可以有\(O(3^n)\)\(O(2^{n^2})\)的做法,但是\(n<=20\),显然在极限情况下这两种做法都是会咕咕咕的。所以我们可以考虑优化\(O(n^3)\)的做法,我们可以想想折半搜索,显然这是可行的,时间复杂度也控制在\(O(2*3^{\frac{n}{2}})\),这是可以接受的。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>

using namespace std;

typedef long long ll;
int n,tot,ans=-1,a[6001],llog2[6001],nxt[4000001],to[4000001];
bool flag[20000001];
map<int,int> head;

void addedge(int x,int y){
	nxt[++tot]=head[x];
	head[x]=tot;
	to[tot]=y;
}

void dfs1(int x,ll sum1,ll sum2){
    if(x>n/2-2){
        if(sum1>=0)addedge(sum1,sum2);
		return;
    }
    int ret=0;
    dfs1(x+1,sum1+a[x],sum2+llog2[x]);
    dfs1(x+1,sum1-a[x],sum2+llog2[x]);
    dfs1(x+1,sum1,sum2);
}

void dfs2(int x,ll sum1,ll sum2){
	for(int i=head[sum1];i;i=nxt[i]){
		int v=to[i];
		if(!flag[v+sum2]){
			flag[v+sum2]=1;
			ans++;
		}
	}
	if(x==n+1)return;
	dfs2(x+1,sum1+a[x],sum2+llog2[x]);
    dfs2(x+1,sum1-a[x],sum2+llog2[x]);
    dfs2(x+1,sum1,sum2);
}

int main(){
	scanf("%d%d",&n,&a[1]);llog2[1]=1;
	for(int i=2;i<=n;i++){
		llog2[i]=llog2[i-1]<<1;
		scanf("%d",&a[i]);
	}	
	dfs1(1,0,0);
    dfs2(n/2-1,0,0);
    printf("%d\n",ans);
    return 0;
}
posted @ 2018-09-06 13:48  ezoiHY  阅读(137)  评论(0编辑  收藏  举报