CF 1444 D. Rectangular Polyline
无聊随便开了一个Div1 D,难度也不是非常大。
首先可以bitset+ dp 搞出所有向上/下/左/右的。
然后你通过旋转之类的让向右的个数>上的个数最终的图就是这样子:
然后可以证明A点的高度一定>=B点的高度。
然后只需要避免这种情况发生就好了。
其实只需要让B下凸,A上凸就好了。
只需要将边排一下序。
code:
/*
{
######################
# Author #
# Gary #
# 2020 #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
// int x=0;
// char ch=getchar();
// while(ch<'0'||ch>'9'){
// ch=getchar();
// }
// while(ch>='0'&&ch<='9'){
// x=(x<<1)+(x<<3)+(ch^48);
// ch=getchar();
// }
// return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int DELTA=1000000;
typedef bitset<2001000+1> BS;
int h,v,l[1001],p[1001];
vector<int> sz[2],sp[2];
BS dp[1001];
void construct(){
bool rev=0;
if(sp[0].size()<sz[0].size()){
sp[0].swap(sz[0]);
sp[1].swap(sz[1]);
rev=1;
}
deque<mp> delta;
while(sz[1].size()>sp[1].size()){
delta.PB({0,-sz[1].back()});
delta.PB({sp[0].back(),0});
sz[1].POB();
sp[0].POB();
}
sort(ALL(sz[0]));
reverse(ALL(sz[0]));
sort(ALL(sp[0]));
sort(ALL(sz[1]));
reverse(ALL(sz[1]));
sort(ALL(sp[1]));
reverse(ALL(sz[0]));
reverse(ALL(sp[0]));
rep(i,sz[0].size()){
delta.push_front({sp[0][i],0});
delta.push_front({0,sz[0][i]});
}
rep(i,sz[1].size()){
delta.PB({0,-sz[1][i]});
delta.PB({-sp[1][i],0});
}
int x=0,y=0;
for(auto dt:delta){
x+=dt.FIR;
y+=dt.SEC;
if(rev){
printf("%d %d
",y,x);
}
else{
printf("%d %d
",x,y);
}
}
}
void solve(){
rep(i,2) sz[i].clear(),sp[i].clear();
rb(i,0,h) dp[i].reset();
scanf("%d",&h);
rb(i,1,h) scanf("%d",&l[i]);
scanf("%d",&v);
rb(i,1,v) scanf("%d",&p[i]);
if(h!=v){
puts("No");
return ;
}
dp[0].set(DELTA);
rb(i,1,h){
dp[i]=(dp[i-1]>>l[i])|(dp[i-1]<<l[i]);
}
if(!dp[h][DELTA]){
puts("No");
return ;
}
int j;
j=DELTA;
rl(i,h,1){
if(dp[i-1][j+l[i]]){
sp[1].PB(l[i]);
j+=l[i];
}
else{
sp[0].PB(l[i]);
j-=l[i];
}
}
rb(i,0,v) dp[i].reset();
dp[0].set(DELTA);
rb(i,1,v){
dp[i]=(dp[i-1]>>p[i])|(dp[i-1]<<p[i]);
}
if(!dp[v][DELTA]){
puts("No");
return ;
}
j=DELTA;
rl(i,v,1){
if(dp[i-1][j+p[i]]){
sz[1].PB(p[i]);
j+=p[i];
}
else{
sz[0].PB(p[i]);
j-=p[i];
}
}
puts("Yes");
construct();
}
int main(){
int t;
scanf("%d",&t);
while(t--) solve();
return 0;
}