A班委竞选
结构体排序。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int vis[105];
struct node{
int id,pos,val;
bool operator<(const node&rhs)const{
if(pos==rhs.pos){
if(val==rhs.val){
return id<rhs.id;
}else return val>rhs.val;
}else return pos<rhs.pos;
}
}a[N];
int main()
{
int n,m,pos,val;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>pos>>val;
a[i].id=i;a[i].pos=pos;a[i].val=val;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
// cout<<a[i].pos<<' '<<a[i].val<<' '<<a[i].id<<'\n';
if(!vis[a[i].pos]){
cout<<a[i].id<<' ';
vis[a[i].pos]=1;
}
}
return 0;
}
C我得重新集结部队
思路:硬模拟。一开始思路理解错了,用队列模拟,后来又读了好几遍题才理清思路。对异虫和折跃狂分析,用结构体存下来他们的信息,然后就模拟事件,出现折跃狂就找最近的异虫对范围内攻击。最后判断。
坑点:
- 寻找最近距离时dist>=2e18,因为极端情况就是2e18,因为这wa了半天没找到原因
- 使用long long 存储数据,距离也是,因为在double下精度会丢失,判断距离的平方即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e3+5;
struct node{
ll x,y,type,h,r,atk,leave;
//x,y坐标,type:0异虫 1 人类 h:异虫生命值 r 攻击范围 atk 攻击 leave 0离开 1留下
}a[N];
ll get_dist(ll x1,ll y1,ll x2,ll y2 )
{
ll d1=x1-x2;
ll d2=y1-y2;
return d1*d1+d2*d2;
}
int main()
{
ll x,y,h,op,n,cnt=1,atk,r;
cin>>n;
for(int i=0;i<n;i++){
cin>>op;
if(op==1){
cin>>x>>y>>h;
a[cnt].type=0;//异虫
a[cnt].x=x;a[cnt].y=y;a[cnt].h=h;
cnt++;
}else{
cin>>x>>y>>atk>>r;
a[cnt].type=1;//人
a[cnt].x=x;a[cnt].y=y;a[cnt].atk=atk;a[cnt].r=r;
int pos=-1;//离异虫最近的位置
ll dist=2e18;
for(int i=1;i<cnt;i++){
if(a[i].type==1||a[i].type==0&&a[i].h<=0)continue;//人或者异虫已死
ll tdist=get_dist(a[cnt].x,a[cnt].y,a[i].x,a[i].y);
if(dist>tdist){
pos=i;dist=tdist;
}
}
a[cnt].leave=1;//默认人会留下,下面异虫没死,人就要离开
if(pos==-1){//异虫全死亡
a[cnt].leave=1;//人留下
}else{//对r范围内的异虫进行攻击
for(int i=1;i<cnt;i++){
if(a[i].type==1||a[i].type==0&&a[i].h<=0)continue;//人或者异虫死亡
ll tdist=get_dist(a[pos].x,a[pos].y,a[i].x,a[i].y);
if(r*r>=tdist){
a[i].h-=3*atk;
if(a[i].h>0)a[cnt].leave=0;
}
}
}
cnt++;
}
}
for(int i=1;i<cnt;i++){
if(a[i].type==0){//异虫
if(a[i].h<=0)cout<<"No";
else cout<<"Yes";
}else{//人
if(a[i].leave==0)cout<<"No";
else cout<<"Yes";
}
cout<<'\n';
}
return 0;
}
/*
5
1 0 0 4
1 0 1 8
2 1 0 1 1
2 1 0 1 1
2 1 0 1 1
No
No
No
No
Yes
*/
E发通知
思路:差分+离散化(扫描线)
通过对时间段左右区间+1,-1。然后求前缀和的过程增加的就是同学的数量,同时用sum进行异或,当从cnt=1到cnt=2时,sum=8^2,再到1时,此时sum=8^2^8=2。所以一直求异或和,并统计同学人数,更新答案即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>PI;
const int N=2e5+5;
map<ll,PI>::iterator it;
map<ll,PI>mp;
int main()
{
ll n,k,l,r,w;
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>l>>r>>w;
mp[l].first++;
mp[r+1].first--;
mp[l].second^=w;
mp[r+1].second^=w;
}
ll cnt=0,sum=0,maxx=-1;
for(it=mp.begin();it!=mp.end();it++){
cnt+=it->second.first;
sum^=it->second.second;
if(cnt>=k){
maxx=max(maxx,sum);
}
}
cout<<maxx<<'\n';
return 0;
}