/***实力还是要努力
D
赛时我过了,就不讲了,毕竟我过的也大概是简单题;
代码:
#include<iostream>
#include<queue>
using namespace std;
#define int long long int t;
int n,m,l;
struct hurdle{int l,r,len;
}hur[500010];
struct power_ups{int x,w;
}pu[500010];void solve(int n,int m,int l){for(int i=1;i<=n;i++){cin>>hur[i].l>>hur[i].r;hur[i].len=hur[i].r-hur[i].l+2;}for(int i=1;i<=m;i++){cin>>pu[i].x>>pu[i].w;}priority_queue<int>q;int ans=0,t=1,cnt=1;for(int i=1;i<=n;i++){if(hur[i].l-1>=l)break;int pos=hur[i].l-1,need=hur[i].len;for(;pu[t].x<=pos&&t<=m;t++){q.push(pu[t].w);}while(!q.empty()&&cnt<need){int u=q.top();cnt+=u;q.pop();ans++;}if(cnt<need){ans=-1;break;}}cout<<ans<<endl;
}signed main()
{cin>>t;while(t--){cin>>n>>m>>l;solve(n,m,l);}return 0;
}
E***
题目大意:交互题!!!这种题我还是很不熟,到现在为止就写过一道。大意就是:有一个长度为n的字符串,可以问一个格式为(l,r)的问题,会得到区间l~r里面有多少01子序列(可不连续)。问能否确定这个字符串?
大致思路:对于交互题不用害怕,可以把它当成“构造题”来思考。如何通过01字串个数确定每一位是0还是1?首先,既然要确定“每一位”,那么我们可以“猜一下”可能每一位都要询问一下。那么我们的思路就是不停问(1,2)(1,3)(1,4)...(1,n)。如果 cnt(1,i+1)==cnt(1,i),那么a[i]=1;否则a[i]=0(前提:i之前已经出现过0)。如果cnt(1,i)是第一个不为0的位置,那么i前面的数是可以确定的,就是i-cnt(1,i)个1,cnt(1,i)个0。如果cnt全是0,那么则不确定。
代码:
#include<iostream>
using namespace std;int t;
int n,a[1000010];int ask(int i){cout<<'?'<<" "<<1<<" "<<i<<endl;int t;cin>>t;return t;
}void solve(int n){int now=0,k1=0,k2=0,flag=0;//第1个非零数前面k1个1,k2个0;for(int i=2;i<=n;i++){int cnt=ask(i);if(cnt>now){a[i]=1;if(now==0){k2=cnt;k1=i-cnt-1;flag=1;}now=cnt;}else{a[i]=0;}}if(flag==0){cout<<"! IMPOSSIBLE\n";}else{cout<<"! ";for(int i=1;i<=k1;i++){cout<<1;}for(int i=1;i<=k2;i++){cout<<0;}for(int i=k1+k2+1;i<=n;i++){cout<<a[i];}cout<<"\n";}
}int main()
{cin>>t;while(t--){cin>>n;solve(n);}return 0;
}
F
题目大意:这题只要会转换就不难,但关键是要想出这么转化。题目大意是,有n个位置,位置x[i]有生命值h[i]。我们可以选择一个位置p,初始攻击值是m,每次攻击距离p l的点会受到攻击m-l。现在要杀掉cnt个位置的生命(生命值<0),最少要进行多少次攻击?(每次攻击选的点p是不变的)
题目思路:用 二分。我们二分攻击次数k。如果一个点x[i]被攻击k次要被杀掉,那么一次就要受到【h[i]/k】(上取整)的攻击值。那么攻击点的位置p就要取在(g-m+x[i],m-g+x[i])的位置。那么其实问题就转化成一个区间覆盖问题。能否找到一个点至少被cnt个区间覆盖。注意要用离散化(或者像我这里用的pair)。
还要注意一下vector排序的问题。vector排序的bool数组里面要用const &,与结构体区分(结构体的话函数会自动赋值)。
代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define int long long
typedef pair<int,int> PII;int t;
int n,m,cnt;
int h[500010],x[500010];
vector<PII>q;
bool sorrt(const PII a,const PII b){return a.first<b.first;
}bool check(int k){//攻击k次可行否?q.clear();for(int i=1;i<=n;i++){int g=h[i]/k;if(h[i]%k){g++;}if(g>m)continue;q.push_back({g-m+x[i],1});q.push_back({m-g+x[i]+1,-1});}sort(q.begin(),q.end());int u=0;for(int i=0;i<q.size();i++){u+=q[i].second;if(u>=cnt)return true;}return false;
}int ef(int l,int r){int mid,ans=-1;while(l<=r){mid=l+r>>1;if(check(mid)){ans=mid;r=mid-1;}else{l=mid+1;}}return ans;
}void solve(int n,int m,int cnt){for(int i=1;i<=n;i++){cin>>h[i];//life length}for(int i=1;i<=n;i++){cin>>x[i];//position}cout<<ef(1,1e9)<<endl;
}signed main()
{cin>>t;while(t--){cin>>n>>m>>cnt;solve(n,m,cnt);}return 0;
}