QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#473916#5416. Fabulous Fungus FrenzyXiaoShanYunPanWA 0ms3916kbC++144.0kb2024-07-12 14:59:452024-07-12 14:59:46

Judging History

你现在查看的是最新测评结果

  • [2024-07-12 14:59:46]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3916kb
  • [2024-07-12 14:59:45]
  • 提交

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