第一题思路很简单,摆物块,最少是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();
}
}
对于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();
}
}
对于如何最小,我们可以将大的数找出来,如果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();
}
}
最小的最大值
想到二分答案
用动态规划思想来思考
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();
}
}