2021.01.28 Rating
B - B
题意:有n个骑士,能量大的能杀死能量小的并吞并他的硬币,但是只能杀死k个骑士,求每个骑士可能获得的最大硬币数。
题解:先将这些骑士按能量的大小从小到大排序,因为一个骑士只能杀死能量比他小的骑士,为了使他所获得的硬币数最大,就要使他所杀死的k个骑士中所包含的硬币数最大(如果能量比他小的骑士的人数小于k,就不需要判断哪k个骑士硬币数最大)。用multiset储存骑士的硬币数,multiset多重集合容器允许重复的元素键值插入。(一开始我是按硬币数从大到小排序,再把能量小于这个骑士的加上然后就超时了)、
用multiset做的
#include<bits/stdc++.h> using namespace std; #define MAXN 100010 typedef long long ll; multiset<ll>s; multiset<ll>::iterator it; struct node{ ll id; ll p; ll c; }a[MAXN]; ll ans[MAXN]; bool cmp(node x,node y){ return x.p<y.p; } int main(){ ios::sync_with_stdio(false); ll n,k; cin>>n>>k; for(int i=1;i<=n;i++){ a[i].id=i; cin>>a[i].p; } for(int i=1;i<=n;i++){ cin>>a[i].c; } sort(a+1,a+n+1,cmp); int cnt=0; for(int i=1;i<=n;i++){ ans[a[i].id]=a[i].c; for(it=s.begin();it!=s.end();it++){ ans[a[i].id]+=*it;//先把能量小的硬币全加上 } s.insert(a[i].c);//把能量小的硬币全存进去 while(s.size()>k){//如果能量小的人大于k个 s.erase(s.begin());//就把硬币最少的删掉直到等于k个 } } for(int i=1;i<=n;i++){ cout<<ans[i]<<" "; } cout<<endl; return 0; }
我自己的超时
#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> using namespace std; #define MAXN 100010 struct node{ int id; int p; long long c; long long sum; }a[MAXN]; bool cmp1(node x,node y){ return x.c>y.c; } bool cmp2(node x,node y){ return x.id<y.id; } int main(){ int n,k; cin>>n>>k; for(int i=1;i<=n;i++){ a[i].id=i; cin>>a[i].p; } for(int i=1;i<=n;i++){ cin>>a[i].c; a[i].sum=a[i].c; } sort(a+1,a+n+1,cmp1); int cnt=0; for(int i=1;i<=n;i++){ cnt=0; for(int j=1;j<=n;j++){ if(cnt==k){ break; } if(a[i].p>a[j].p){ a[i].sum+=a[j].c; cnt++; } } } sort(a+1,a+1+n,cmp2); for(int i=1;i<=n;i++){ cout<<a[i].sum<<" "; } cout<<endl; return 0; }
C - C
题意:给出平行于x轴的正方形的四个顶点和与x轴成45度倾斜的正方形的四个顶点,判断两个正方形是否相交。
题解:数据范围小,如果两个正方形相交则一定有一个整数点重合,所以判断两个正方向中是否有重合的整数点。对于倾斜的正方形,由于他的每条边的斜率都可知,可根据线性规划判读点是否属于倾斜正方形。(看了好多人做的都理解不了,只有这个做法我能整明白。)
#include<bits/stdc++.h> using namespace std; struct node{ int x,y; }p[50000],q[50000];//我开40010 RE了 int main(){ ios::sync_with_stdio(false); int x,y; int minx1=110,maxx1=-110,miny1=110,maxy1=-110; int minx2=110,maxx2=-110,miny2=110,maxy2=-110; for(int i=1;i<=4;i++){ cin>>x>>y; minx1=min(x,minx1); maxx1=max(x,maxx1); miny1=min(y,miny1); maxy1=max(y,maxy1); } for(int i=1;i<=4;i++){ cin>>x>>y; minx2=min(x,minx2); maxx2=max(x,maxx2); miny2=min(y,miny2); maxy2=max(y,maxy2); } int cnt1=0,cnt2=0; for(int i=minx1;i<=maxx1;i++){ for(int j=miny1;j<=maxy1;j++){ cnt1++; p[cnt1].x=i; p[cnt1].y=j; } } int a,b,c,d; int tx=(maxx2+minx2)/2; int ty=(maxy2+miny2)/2; for(int i=minx2;i<=maxx2;i++){ for(int j=miny2;j<=maxy2;j++){ a=j-ty-i+minx2;//对应的直线为y-ty=x-minx2; b=j-ty-i+maxx2;//y-ty=x-maxx2; c=j-ty+i-maxx2;//y-ty=-(x-maxx2) d=j-ty+i-minx2;//y-ty=-(x-minx2) //因为tx,ty在正方形里,可以通过线性规划来进行判断 if(a<=0&&b>=0&&c<=0&&d>=0){ cnt2++; q[cnt2].x=i; q[cnt2].y=j; } } } int flag=0; //依次判断有没有点重合 for(int i=1;i<=cnt1;i++){ for(int j=1;j<=cnt2;j++){ if(p[i].x==q[j].x&&p[i].y==q[j].y){ flag=1; } if(flag) break; } if(flag) break; } if(flag){ cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } return 0; }

浙公网安备 33010602011771号