A. Brick Wall
读题不谨慎翻车半小时,警惕黑体加粗的单词,真的很重要。
给你n高,m宽的方框,往里面放 1*k 大小的砖头,k自己选,但是>=2,塞满方框的情况并且不超出边界,输出最大的平衡值(横砖数量减去竖砖数量)(同时方框里面 k 可以不全都是一样的)
就是 Note 后面的一段,没看到的话这道题就难做了(指样例一直过不了到处找bug,结果题目看漏了)。
思路很简单,横的要多那就全放1*2的横砖,有留空塞不满的就不用管(相当于最后的2拉长填满剩下的),此时就是最多的。
#include <bits/stdc++.h>
//#define int long long
#define per(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define rep(i,j,k) for(int (i)=(j);(i)>=(k);--(i))
#define fr first
#define se second
#define endl '\n'
using namespace std;
int n,m;
void solve(){
cin>>n>>m;
int tmp=0;
while(m>=2){//这里就是m/2 看到黑体单词的时候已经小脑萎缩了
m-=2;
tmp++;
}
cout<<tmp*n<<endl;
}
void init(){
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;//单组数据删除cin>>t,将此处改为t=1
cin>>t;
while(t--)solve(),init();
return 0;
}
B. Minimize Inversions
题意:任意的 i<j 且 ai>aj(某一个数后面比他小的数)记作一个投资、也就是逆序对,我们可以任选 i,j 交换 ai,aj,可以无限次操作,然后再给你一个序列,你对原序列的操作要同步执行到这个序列上。要求输出操作后最小的逆序对数量情况下的两个序列。
思路:因为交换会影响到两个序列,所以要上下都要考虑进去,并且一上一下作为一个整体来看待。
比如 a: 4 5
b: 6 7
把a1和b1上下框起来看做一个整体,a2和b2上下框起来看做一个整体,分析可以得出三种情况。
1. a1<a2
b1<b2
这种情况a1和b1不会产生逆序对,所以要放a1和b1在左边。
2. a1>a2
b1>b2
这种情况a1和b1会产生两个逆序对,a1和b1必须交换到a2和b2的后面。
3. a1>a2 或 a1<a2
b1<b2 b1>b2
这种情况会产生一个逆序对,那就把他们按照升序放在一起,遇到临界条件1和2了再做改变就完事了。
分析完之后发现,这三个条件使用sort和很容易实现,于是这道题就结束了。
题目限制范围所有测试集的n总和不会大于2e5
那么大概 n^2 及以下能过这道题。
#include <bits/stdc++.h>
//#define int long long
#define per(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define rep(i,j,k) for(int (i)=(j);(i)>=(k);--(i))
#define fr first
#define se second
#define endl '\n'
using namespace std;
const int N=2e5+5;
struct Node{
int a,b;
}sn[N];
int n;
void solve(){
cin>>n;
per(i,1,n)cin>>sn[i].a;
per(i,1,n)cin>>sn[i].b;
sort(sn+1,sn+1+n,[](Node A,Node B){
if(A.a<B.a and A.b<B.b){//条件1
return true;
}else if(A.a>B.a and A.b>B.b){//条件2
return false;
}else return A.a<B.a;//条件3,A.b<B.b也可以
});
per(i,1,n)cout<<sn[i].a<<" ";
cout<<endl;
per(i,1,n)cout<<sn[i].b<<" ";
cout<<endl;
}
void init(){
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--)solve(),init();
return 0;
}
条件3为什么只需要任意选一行升序?
有没有可能上面升序带来的逆序对 比 下面升序带来的逆序对 更少?
假设有条件3的情况如下,任意两个均为1个逆序对,且按照上面排序
10 20 30 40 55 B
90 40 30 20 15 C
根据条件2可得 B和C能在右边 取值必须要大于左边的最大值
随便取值即
10 20 30 40 55 56
90 40 30 20 15 91
按照上面排序的时候最大值55就已经小于56了
按照下面排序,那上面只会出现比55更小的数,所以此问题不会有成立的情况。
哪怕下面大小满足了,上面永远找不出比55更大的数,不能实现逆序对更少。