Codeforces Round 922 (Div. 2)(A-D)

A:Brick Wall

第一题思路很简单,摆物块,最少是2你会发现如果y是奇数最后放3*1,否则2*1,总之就是

m/2*n;

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int,int>pii;
#define N 300000
int a[N],b[N];
void solve(){
      int a,b;
      cin>>a>>b;
      b=b/2;
      cout<<a*b<<endl;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

B:Minimize Inversions

对于A,B两个数组来说如果条件满足,就交换这两个位置上的数,其实A,B数组同一位置实际上是绑定的,通过排序发现逆序对是最少的,偏向于思维

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int,int>pii;
#define N 300000
pii a[N],b[N];
void solve(){
      int n;
      cin>>n;
      for(int i=0;i<n;i++) cin>>a[i].first;
      for(int i=0;i<n;i++) cin>>a[i].second;
      int flag=0,mi=0,mx=0;
      sort(a,a+n);
      for(int i=0;i<n;i++) cout<<a[i].first<<" ";
      cout<<endl;
       for(int i=0;i<n;i++) cout<<a[i].second<<" ";
      cout<<endl;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

C:XOR-distance

对于如何最小,我们可以将大的数找出来,如果a<b,则交换

开始分析,我们目标是把大数变小,小的变大

从最高位往下进行枚举,但是如果a最高位是1,b为0,不要把这一位的数减掉,因为这样会使数变大,之后看到a某一位为1,b为0,通过异或的性质来把a变小,b变大这样总之会是最小的数

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int,int>pii;
#define N 300000
void solve(){
    int a,b,c;
    cin>>a>>b>>c;
    if(a<b)  swap(a,b);
    int s=0;
    //int cnt=0;
    int cnt=0;
    for(int i=60;i>=0;i--){
        int x = a >> i & 1;
        int y = b >> i & 1;
       if (x > y)
      {
        if(cnt!=0&&s + (1ll << i) <= c) s |= 1ll << i;
        cnt++;
      }
 }
	cout<<abs((a^s)-(b^s))<<endl;
	
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

D:D - Blocking Elements

最小的最大值
想到二分答案
用动态规划思想来思考
dp[i]表示前i中最小的并且满足小于x
用大根堆(优先队列)维护最小值并且满足在当前区间内

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int,int>pii;
#define N 300000
int n;
int a[N];
int dp[N];
bool check(int x){
	int sum=0,now=0;
	int l=1;
	priority_queue<pii,vector<pii>,greater<pii>>q;
	q.push({0,0});
	for(int r=1;r<=n+1;r++){
		while(now>x) now-=a[l++];
		while(!q.empty()&&q.top().second<l-1) q.pop();
		dp[r]=q.top().first+a[r];
		q.push({dp[r],r});
		now+=a[r];
	}
	return dp[n+1]<=x;
}
void solve(){
	 
	 cin>>n;
	 for(int i=1;i<=n;i++) cin>>a[i];
	 a[n+1]=0;
	 int l=1,r=1e18;
	 while(l<=r){
	 	int mid=l+r>>1;
	 	if(check(mid)) r=mid-1;
	 	else l=mid+1;
	 }
	 if(check(l)) cout<<l<<endl;
	 else cout<<r<<endl;
}
signed main(){
    int t;
    cin>>t;
    while(t--){
       solve();
    }
}

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多年以后

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值