题意:一个n大小的数组,一个操作可以删除一个数字,并且可以随便排列,问操作几次,可以使相邻的最大的差≤k
思路:排序,算符合条件的区间
代码:
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n,k;
cin>>n>>k;
vector<int>q(n);
for (int i = 0; i <n ; ++i) {
cin>>q[i];
}
sort(q.begin(),q.end());
int ls=0;
// for (int i = 0; i < n; ++i) {
// cout<<q[i]<<' ';
// }
int cnt=1;
vector<int >ans;
int dq=q[0];
for (int i = 1; i <n ; ++i) {
if(q[i]-dq<=k){
cnt++;
dq=q[i];
}
else{
ans.push_back(cnt);
cnt=1;
dq=q[i];
}
}
ans.push_back(cnt);
cout<<(n-*max_element(ans.begin(),ans.end()))<<endl;
}
int main(){
int t;
cin>>t;
while (t--){
solve();
}
}
思路:二分,记得开__int128,快读,快写
代码:
#include<bits/stdc++.h>
using namespace std;
#define int __int128
int read()
{
int res=0;
char scan[1005];
scanf("%s",scan);
for(int i=0;i<strlen(scan);i++)
res*=10,res+=scan[i]-'0';
return res;
}
void solve(){
int n,c;
n=read(),c=read();
vector< int >q(n);
for (int i = 0; i <n ; ++i) {
q[i]=read();
}
auto check=[&](int mid){
int g=mid*2;
int sum=0;
for (int i = 0; i <n ; ++i) {
int k=q[i]+g;
sum+=k*k;
}
return sum>=c;
};
int l=0,r=1e9;
int ans;
while (l<=r){
int mid=l+r>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}
else{
l=mid+1;
}
}
long long res=ans;
cout<<res<<endl;
}
signed main(){
int t;
t=read();
while (t--){
solve();
}
}
题意:n个青蛙的跳跃距离是ai,问陷阱放在哪个位置,捕捉的青蛙最多
思路:枚举到每个青蛙时,记录一下他能跳跃到的位置,然后算一下每个位置的捕捉到的青蛙的个数
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n;
cin>>n;
map<int,int>q;
for (int i = 0; i <n ; ++i) {
int x;
cin>>x;
if(x<=n){
q[x]++;
}
}
vector<int>dian(n+1,0);
int ans=0;
for (auto i:q) {
int k=i.first;
for (int j = k; j <=n ; j+=k) {
dian[j]+=q[k];
ans=max(ans,dian[j]);
}
}
cout<<ans<<endl;
}
signed main(){
int t;
cin>>t;
while (t--){
solve();
}
}
题意:给n个点,问组成的线是8个方向上的线有几个
思路:映射一下,四个直线,x轴,y轴,x-y轴,x+y轴,然后两两结合
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
map<int,int>mpx,mpy;
int n;
cin>>n;
map<int,int>q1,q2;
for (int i = 0; i <n ; ++i) {
int x,y;
cin>>x>>y;
mpx[x]++;
mpy[y]++;
q1[x-y]++;
q2[x+y]++;
}
int ans=0;
for (auto i:q1) {
ans+=(i.second)*(i.second-1);
}
for (auto i:q2) {
ans+=(i.second)*(i.second-1);
}
for (auto i:mpx) {
ans+=(i.second-1)*(i.second);
}
for (auto i:mpy) {
ans+=(i.second-1)*i.second;
}
cout<<ans<<endl;
}
signed main(){
int t;
cin>>t;
while (t--){
solve();
}
}
题意:给n个士兵,每个士兵都必须只属于一个营地,营地在x轴上,给m个条件,每个条件3个数字 a,b,c比如给 a,b,c,是指b在a的前面c米处,问这些条件有没有假的(冲突的)
思路:我们可以根据条件建图,然后对每一个点BFS搜索,如果这个点没有被搜过,加入继续搜,如果被搜过了,查询一下之前搜到的距离与这次搜到的距离是否相等,如果不相等,那么就冲突。
代码:
#include<bits/stdc++.h>
using namespace std;
int const N=1e4+5;
#define int long long
void solve(){
int n,m;
cin>>n>>m;
vector<pair<int,int>>q[n+1];
vector<int>dis(n+1),vis(n+1);
for (int i = 0; i <m ; ++i) {
int x,y,c;
cin>>x>>y>>c;
q[x].push_back({y,c});
q[y].push_back({x,-c});
}
for (int i = 1; i <=n ; ++i) {
if(!vis[i]){
queue<int >que;
que.push(i);
dis[i]=0;
while (que.size()){
auto t=que.front();
que.pop();
for (auto [x,y]:q[t]) {
if(!vis[x]){
dis[x]=dis[t]+y;
que.push(x);
vis[x]=1;
}
else if(dis[x]!=dis[t]+y){
cout<<"no\n";
return;
}
}
}
}
}
cout<<"yes\n";
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while(t--){
solve();
}
}
/*
*
*/