QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#473916 | #5416. Fabulous Fungus Frenzy | XiaoShanYunPan | WA | 0ms | 3916kb | C++14 | 4.0kb | 2024-07-12 14:59:45 | 2024-07-12 14:59:46 |
Judging History
answer
/*
智!巧!灵!蕈!大!竞!逐!
原神,启动!
---
正着做是十分困难的。
考虑从结束状态倒推到初始状态
发现操作3——盖章操作这时候变得十分的好
只要我凑出一个章,就可以把这个章覆盖的区域全部变成万能符
于是我们可以考虑不停凑章:
判断一个章是否能被凑出来,如果可以就凑;否则判断下一个章
直到发现所有章都凑不出来为止。
然后看现在能不能凑出初始状态,就可以判断是否有解了
分析一下限制
盖一个章,至少会增加1个万能符
那最多就只会盖n*m<=400个章,刚好符合题目限制
就算我凑一个章需要n*m次操作,最多也就n*m*400=160000,限制还是比较宽松的
判断、操作一个章如果都压到O(nm),那复杂度就是O(n^2m^2k)
*/
#include<bits/stdc++.h>
using namespace std;
constexpr int N=25;
int nn[N],mm[N],nb,num[N][130],n,m;
bool check(int t){
//printf("check(%d)\n",t);
int tp=nb;
for(int i=48;i<=122;++i)tp-=max(num[t][i]-num[0][i],0);
//printf("tp=%d nb=%d\n",tp,nb);
return tp>=0&&nb-tp<nn[t]*mm[t];
}
bool eq(char x,char y){return x==y||x==35||y==35;}
int dist(int x,int y,int p,int q){return abs(x-p)+abs(y-q);}
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
bool vis[N][N];
char nw[N][N];
struct B{int op,x,y;};
vector<B>ans;
void move(int x,int y,int edx,int edy){
//printf("move(%d,%d,%d,%d)\n",x,y,edx,edy);
while(x!=edx||y!=edy){
for(int i=0;i<4;++i){
int p=x+dx[i],q=y+dy[i];
if(p>n||q>m)continue;
if(!vis[p][q]&&dist(p,q,edx,edy)<dist(x,y,edx,edy)){
ans.push_back({i-4,x,y});
swap(nw[x][y],nw[p][q]);
//printf("swap(nw[%d][%d],nw[%d][%d])\n",x,y,p,q);
x=p,y=q;
break;
}
}
}
}
char zh[N][N][N];
void work(int t){
//printf("work(%d):\nzh[%d]:\n",t,t);
//for(int i=1;i<=nn[t];++i){
// for(int j=1;j<=mm[t];++j)cout<<zh[t][i][j];
// putchar(10);
//}
for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)vis[i][j]=0;
//puts("just int work:");
//for(int i=1;i<=n;++i){
// for(int j=1;j<=m;++j)cout<<nw[i][j];
// putchar(10);
//}
//cout<<"nw[3][1]="<<nw[3][1]<<endl;
for(int i=1;i<=nn[t];++i){
for(int j=1;j<=mm[t];++j){
int p,q;
for(p=1;p<=n;++p)for(q=1;q<=m;++q)if(!vis[p][q]&&nw[p][q]==zh[t][i][j])goto out;
//printf("p=%d q=%d\n",p,q);
if(p>n||q>m)for(/*puts("in extra find"),*/p=1;p<=n;++p)for(q=1;q<=m;++q)if(!vis[p][q]&&eq(nw[p][q],zh[t][i][j]))goto out;
out:
if(p>n||q>m)assert(0);
move(p,q,i,j);
vis[i][j]=1;
}
}
//puts("before turn into nb:");
//for(int i=1;i<=n;++i){
// for(int j=1;j<=m;++j)cout<<nw[i][j];
// putchar(10);
//}
//printf("nb=%d\n",nb);
for(int i=1;i<=nn[t];++i)for(int j=1;j<=mm[t];++j)if(nw[i][j]!=35)--num[0][nw[i][j]],nw[i][j]=35,++nb;
//puts("after turn into nb:");
//for(int i=1;i<=n;++i){
// for(int j=1;j<=m;++j)cout<<nw[i][j];
// putchar(10);
//}
//printf("nb=%d\n",nb);
ans.push_back({t,1,1});
}
int k,i,j;
int main(){
scanf("%d%d%d",&n,&m,&k);
nn[k+1]=n,mm[k+1]=m;
for(i=1;i<=n;++i)for(j=1;j<=m;++j)cin>>zh[k+1][i][j],++num[k+1][zh[k+1][i][j]];//把终点状态也看成一个章
getchar();
for(i=1;i<=n;++i)for(j=1;j<=m;++j)cin>>nw[i][j],++num[0][nw[i][j]];
getchar();
for(i=1;i<=k;++i){
scanf("%d%d",nn+i,mm+i);
for(int p=1;p<=nn[i];++p)for(int q=1;q<=mm[i];++q)cin>>zh[i][p][q],++num[i][zh[i][p][q]];
if(i<k)getchar();
}
//为了方便,我们不妨钦定每个章都在左上角盖
while(1){
bool flag=0;
for(i=1;i<=k;++i){
if(check(i)){
//puts("in");
flag=1;
work(i);
}
}
//printf("%d\n",(int)ans.size());
//for(i=ans.size()-1;~i;--i)printf("%d %d %d\n",ans[i].op,ans[i].x,ans[i].y);
if(!flag)break;
}
if(check(k+1)){
work(k+1);
ans.pop_back();
printf("%d\n",(int)ans.size());
for(i=ans.size()-1;~i;--i)printf("%d %d %d\n",ans[i].op,ans[i].x,ans[i].y);
}
else puts("-1");
//for(int i=1;i<=n;++i){
// for(int j=1;j<=m;++j)cout<<nw[i][j];
// putchar(10);
//}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3916kb
input:
3 3 1 OOO GOG BGB OOO GGG BBB 3 1 B G B
output:
28 -4 2 3 -4 3 3 -2 1 3 -4 2 3 -2 1 2 -2 1 3 1 1 1 -2 3 2 -3 2 2 -3 1 2 -2 2 2 -2 2 3 -4 3 3 1 1 1 -2 3 2 -3 2 2 -3 1 2 -2 2 2 -4 3 2 -2 1 2 -2 1 3 -4 2 3 -4 3 3 1 1 1 -2 3 2 -2 2 2 -4 2 1 -4 3 1
result:
ok puzzle solved
Test #2:
score: 0
Accepted
time: 0ms
memory: 3648kb
input:
2 2 1 OO OO PP PP 1 2 OP
output:
-1
result:
ok puzzle solved
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3688kb
input:
4 8 4 11122222 33344444 55556666 77777777 NIxSHUOx DExDUIxx DANxSHIx YUANSHEN 2 3 NIy DEx 3 8 zzzzzzzz DANNSH9I YUA9SHEN 1 1 x 2 5 SHO8y DUUI8
output:
-1
result:
wrong answer solvable puzzle unsolved