A——Find K Distinct Points with Fixed Center
n为偶数输出
n为奇数输出
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int x,y,k;
cin>>x>>y>>k;
if(k%2)
{
cout<<x<<' '<<y<<'\n';
for(int i=1;i<=(k-1)/2;i++)
{
cout<<x+i<<' '<<y+i<<'\n';
cout<<x-i<<' '<<y-i<<'\n';
}
}
else
{
for(int i=1;i<=k/2;i++)
{
cout<<x+i<<' '<<y+i<<'\n';
cout<<x-i<<' '<<y-i<<'\n';
}
}
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
B——Minimize Equal Sum Subarrays
使原数组的每个数取余n,然后再加1,即
这样不包含n的每个长度为的区间都比原数组区间大,包含n的每个长度为的区间比原数组区间与原数组相差 (减少了,除了以外每个数比原来大)
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int p[N],q[N];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>p[i];
}
for(int i=1;i<=n;i++)
{
q[i]=p[i]%n+1;
cout<<q[i]<<' ';
}
cout<<'\n';
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
C——Perform Operations to Maximize Score
首先先排序,分析可知最大值只能由两种情况更新过来
1.当前位置可加,
2.当前位置不可加,
表示当前的值,表示去掉第个数可增加时中位数最大是多少
容易想到使用二分求得,如果数组里面去掉后仍存在个超过mid的数(包括可增加的数),则返回ture,否则返回false
但是这样的时间复杂度为,明显需要优化
观察情况二可以发现
与等价(相当于把变成)
轻易可以发现永远大于,故情况二只需要算出与情况一取即可
时间复杂度
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
pair<ll,int> p[N];
ll a[N];
int b[N];
ll n,k;
bool check(ll u,ll k)
{
int cnt=0;
for(int i=n-1;i>=1;i--)
{
if(p[i].first>=u) cnt++;
else if(p[i].second&&p[i].first+k>=u)
{
k-=u-p[i].first;
cnt++;
}
}
if(cnt!=0&&cnt>=(n+1)/2) return 1;
return 0;
}
void solve()
{
ll ans=0;
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
p[0]={0,0};
for(int i=1;i<=n;i++) p[i]={a[i],b[i]};
sort(p+1,p+1+n);
int mid=(n+1)/2;
for(int i=1;i<=n;i++)
{
if(p[i].second==1)
{
if(n%2==1)
{
if(i<mid) ans=max(ans,p[mid].first+p[i].first+k);
else ans=max(ans,p[mid-1].first+p[i].first+k);
}
else
{
if(i<=mid) ans=max(ans,p[mid+1].first+p[i].first+k);
else ans=max(ans,p[mid].first+p[i].first+k);
}
}
}
ll l=1,r=1e9+10;
while(l<r)
{
ll mid=(l+r+1)/2;
if(check(mid,k)) l=mid;
else r=mid-1;
}
// cout<<l<<'\n';
// for(int i=1;i<=n;i++) cout<<p[i].first<<' '<<p[i].second<<'\n';
ans=max(ans,p[n].first+l);
cout<<ans<<'\n';
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
D——Determine Winning Islands in Race
题意简述:、两人比赛谁先到达 点, 只能从第 个点到第 个点, 可以在有桥的情况下从点直接到 点但是起始点只能在 点,两者都不能走对方走过的路,输出当 的起始位置在 时是否能获胜
分析可知当 通过桥到达 的前面时, 将永远无法到达 点, 会失败
所以当 的位置为 时,我们需要对每一个 到 到 的点进行判断,找出 到该点所需的步数 ( ),如果 说明 比 更早到达该点, 无法通过该点限制 的行动,为了方便比较我们化简一下判断条件,当 时该点不能阻挡 ,对于 如果 ( ) 恒成立
即时输出 ,在计算 时我发现只有桥的左端点在 右侧时才有效,在 左侧,如果该点无法阻挡 那与它相连的点也无法阻挡 如果该点可以阻挡,那与它相连的点也可以阻挡, 并且当桥的右端点在 左侧时也永远无法阻挡
故。所以首先按桥的左端点排序,从 遍历,遍遍历边加边减边,用优先队列维护()的最大值即可。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,M=2*N;
typedef pair<int,int> PII;
int n,m;
PII v[N];
int len[N];
const int inf=0x3f3f3f3f;
void init()
{
for(int i=1;i<=n;i++) len[i]=i-1;
}
struct cmp{
bool operator ()(const PII &a,const PII &b)
{
if(a.first == b.first) return a.second>b.second;
return a.first<b.first;
}
};
void solve()
{
priority_queue<PII,vector<PII>,cmp> pq;;
cin>>n>>m;
init();
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
v[i]={a,b};
}
sort(v+1,v+1+m);
int d=1;
for(int i=1;i<n;i++)
{
len[i]=min(len[i],len[i-1]+1);
while(d<=m&&v[d].first<i)
{
int a=v[d].first,b=v[d].second;
len[b]=min(len[b],len[a]+1);
pq.push({b-len[b],b});
d++;
}
while(pq.size())
{
PII it=pq.top();
if(it.second<=i) pq.pop();
else break;
}
if(pq.size()==0)
{
cout<<1;
continue;
}
PII it=pq.top();
if(i>=it.first) cout<<1;
else cout<<0;
}
cout<<'\n';
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}