链接地址,帐号:team2079,密码:062226
误认为题意求的是每个箱子内宝物价值的总和和箱子价值之差的和,想了好久发现不能做。赛后有人告诉我这是NP问题。
其实题意求就是给每一个宝物找一个箱子,只要这个宝物与箱子的差最小,最后的结果也是最小的。所以,问题转化对于每个a[i],在数列b中找到一个最接近的b[j]。可以通过STL中的lower_bound来查找r,之后l=r-1。要注意的有两点:r=m时,是越界的,r=r-1;r=0时,l=r-1。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int inf=0x3fffffff;
int ans,tp,a[100000+5],b[100000+5],n,m;
int main()
{
int t,i,j,k,l,r;
while(~scanf("%d%d",&n,&m))
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<m;i++)
scanf("%d",&b[i]);
sort(a,a+n);
sort(b,b+m);
ans=0;
for(i=0;i<n;i++)
{
r=lower_bound(b,b+m,a[i])-b;
if(r==m)
{
r--;
l=r;
}
else
{
if(r!=0) l=r-1;
else l=r;
}
tp=min(abs(a[i]-b[l]),abs(b[r]-a[i]));
ans=ans+tp;
}
printf("%d\n",ans);
}
return 0;
}
最大生成树,用那个k开头的算法就可以了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
typedef vector<int> VI;
typedef long long ll;
struct edge
{
int a,b,w;
}Edge[200*200];
int cmp(edge x,edge y)
{
return x.w>y.w;
}
int p[200],n;
int Find(int x)
{
if(x==p[x]) return p[x];
else return p[x]=Find(p[x]);
}
int main()
{
int i,j,w,tot,ans,u,v,fu,fv;
while(~scanf("%d",&n))
{
tot=0;
ans=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
scanf("%d",&w);
Edge[tot].a=i;
Edge[tot].b=j;
Edge[tot].w=w;
tot++;
}
sort(Edge,Edge+tot,cmp);
for(i=0;i<200;i++) p[i]=i;
for(i=0;i<tot;i++)
{
u=Edge[i].a;
v=Edge[i].b;
w=Edge[i].w;
fu=Find(u);
fv=Find(v);
if(fu!=fv)
{
ans+=w;
p[fu]=fv;
}
}
printf("%d\n",ans);
}
return 0;
}
二进制规律,除了0和0的或为0,其他都为1.所以将X和Y转为二进制之后,每一位相加考虑,X中为1的位,必定Y中对应的位上数字为0。所以查找第k个就是将k也转化为二进制,从低位开始填充到x中值为0的位上。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
typedef vector<int> VI;
typedef long long ll;
int main()
{
int _,a[200],ta,tb,b[200],ans[200],i,j,t;
ll x,k,as;
scanf("%d",&_);
while(_--)
{
scanf("%lld%lld",&x,&k);
//int tot=0;
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
t=ta=tb=0;
while(x)
{
a[ta]=x%2;
x/=2;
ta++;
}
while(k)
{
b[tb]=k%2;
k/=2;
tb++;
}
i=0;
for(j=0;j<ta;j++)
{
if(a[j]==0)
{
ans[t++]=b[i++];
}
else ans[t++]=0;
if(i>=tb) break;
}
while(i<tb)
{
ans[t++]=b[i++];
}
as=0;
ll tp=1;
for(i=0;i<t;i++)
{
if(ans[i]==1)
{
as+=tp;
}
tp=tp*2;
}
printf("%lld\n",as);
}
return 0;
}
模拟
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
typedef vector<int> VI;
typedef long long ll;
int main()
{
int wh,wa,wd,bh,ba,bd,f,tw,tb;
char s[10];
while(~scanf("%s",s))
{
scanf("%d%d%d",&wh,&wa,&wd);
scanf("%d%d%d",&bh,&ba,&bd);
tw=wa-bd;
tb=ba-wd;
if(tw<=0) f=0;
else
{
if(s[0]=='B')
wh-=tb;
if(wh<=0) {f=0;}
else{
while(1)
{
bh-=tw;
if(bh<=0)
{f=1;break;}
wh-=tb;
if(wh<=0)
{f=0;break;}
}
}
}
if(f==1)
printf("Warrior wins\n");
else
printf("Warrior loses\n");
}
return 0;
}