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;
}