问题 A: Three-Axis Views
给出一个立方体的三个视图,问这样的立方体是否存在。
最初的思路是通过图
1
,
2
1,2
1,2的
z
z
z坐标确定出
(
x
,
y
)
(x,y)
(x,y),看这样的
(
x
,
y
)
(x,y)
(x,y)在图
3
3
3里是否也存在。
但是应该对
x
x
x坐标确定的
(
y
,
z
)
(y,z)
(y,z)和
y
y
y坐标确定的
(
x
,
z
)
(x,z)
(x,z)也做相同的检查。
int n;
int mp[4][110][110];
char s[110];
int b[4][110][110];
int las[110][110][110];
int main(){
n=read;
rep(i,0,2){
for(int j=1,t=n;j<=n;j++,t--){
cin>>s+1;
for(int k=1;k<=n;k++){
if(s[k]=='1'){
mp[i][k][t]=1;
}
}
}
}
rep(i,1,n) rep(j,1,n) rep(k,1,n)
if(mp[0][j][k]&&mp[1][k][i]&&mp[2][i][j])
b[0][j][k]=b[1][k][i]=b[2][i][j]=1;
rep(i,0,2) rep(j,1,n) rep(k,1,n){
if(b[i][j][k]!=mp[i][j][k]){
cout<<"No";return 0;
}
}
cout<<"Yes";
return 0;
}
B: Secrets of Legendary Treasure
题意:
给出一个长度为
n
n
n的序列
a
a
a和长度为
m
m
m的序列
b
b
b。其中
a
,
b
a,b
a,b里非
0
0
0的位置要填充上
[
1
,
n
+
m
]
[1,n+m]
[1,n+m]的整数,并且每个数只能够出现一次。输出方案数。
思路:
记录下序列
a
,
b
a,b
a,b里非
0
0
0位的数值和位置,每次取最小的,将中间的一段填上数。
注意:
每次填数的时候从
1
1
1开始,填未被填过的数并且填的数的大小也合法
如果序列的最后一个位置是
0
0
0的话,要再记录一下
n
+
1
n+1
n+1或
m
+
1
m+1
m+1的位置
const int maxn=2e5+100,inf=0x3f3f3f3f;
const double eps=1e-5;
int n,m,a[maxn],b[maxn];
bool vis[maxn];
vector<PII>pa,pb;
int main(){
n=read,m=read;
rep(i,1,n){
int x=read;
a[i]=x;
if(x!=0) pa.push_back({x,i});
vis[x]=1;
}
if(a[n]==0) pa.push_back({n+m+1,n+1});
rep(i,1,m){
int x=read;
b[i]=x;
if(x!=0) pb.push_back({x,i});
vis[x]=1;
}
if(b[m]==0) pb.push_back({n+m+1,m+1});
int now=1,cnta=0,cntb=0,ta=0,tb=0,lasta=1,lastb=1;
while(ta<pa.size()||tb<pb.size()){
int nowa=1e9,nowb=1e9;
if(ta<pa.size()) nowa=pa[ta].first;
if(tb<pb.size()) nowb=pb[tb].first;
now=1;
if(nowa<nowb){
for(int i=lasta;i<=pa[ta].second-1;i++){
while(vis[now]||now<cnta) now++;
a[i]=now;vis[now]=1;
}
a[pa[ta].second]=nowa;vis[nowa]=1;
lasta=pa[ta].second+1;
cnta=pa[ta].first;
ta++;
}
else{
for(int i=lastb;i<=pb[tb].second-1;i++){
while(vis[now]||now<cntb) now++;
b[i]=now;vis[now]=1;
}
b[pb[tb].second]=nowb;vis[nowb]=1;
lastb=pb[tb].second+1;
cntb=pb[tb].first;
tb++;
}
}
rep(i,1,n) cout<<a[i]<<" ";
puts("");
rep(i,1,m) cout<<b[i]<<" ";
return 0;
}