洛谷 P2630 图像变换

这道题其实就是纸老虎,看上去10e8很大,其实根本就不会达到那么大。若有解,必定不会超过4个字符。

reason:AA是不是就等于BB了?而AAA是不是又等于B了?所以A和B一共出现2次。而DD抵消,CC抵消,所以各只出现一次,所以最多四次。
了解到这一切之后就知道忧愁祸患使人生存,安逸享乐会使人死亡的道理了????,那么直接上暴力深搜伺候
细节在代码里嘤

没人 比我 更懂 code:

#include <bits/stdc++.h>
using namespace std;
int k;
int a[4][4] , b[4][4];	//当前 / 目标 
map<char , int> f;	//记录出现次数 
map<char , int> bz;	//变阻真帅(误) 没实际作用,忘删了而已 
stack<char> ans;	//目前搜到的答案 
stack<char> eans;	//最优解 
bool pd(){ //判断是否到达 
	for(int i = 1; i <= 3; i++)
		for(int j = 1; j <= 3; j++) if(a[i][j] != b[i][j]) return 0;
	return 1;
}
void search(){
	//cout << ans.top();
	/*cout << endl;
	for(int i = 1; i <= 3; i++){
		for(int j = 1; j <= 3; j++) cout << a[i][j] << " ";
		cout << endl;
	}*/
	if(pd()){
		if(ans.size() < eans.size()){
			while(!eans.empty()) eans.pop();
			char ccc[60];
			int i = 1;
			while(!ans.empty()){	//!!!!特别注意栈是先进后出,所以得用这种转移方式 
				ccc[i] = ans.top();
				ans.pop();
				i++;
			}
			for(int j = i; j >= 1; j--){
				eans.push(ccc[j]);
				ans.push(ccc[j]);
			}
		}
		k = 1;	//有解 
	}
	if(f['A'] + f['B'] != 2){	//AB总共不出现两次/剪枝 
		bz['A']++;
		f['A']++;
		ans.push('A');
		int ca[4][4];
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) ca[i][j] = a[i][j];
		for(int i = 1; i <= 3; i++)
        	for(int j = 1; j <= 3; j++) a[i][j] = ca[3 - j + 1][i];
		search();
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) a[i][j] = ca[i][j];
		ans.pop();
		f['A']--;
	}
	if(f['A'] + f['B'] != 2){
		bz['B']++;
		f['B']++;
		ans.push('B');
		int cb[4][4];
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) cb[i][j] = a[i][j];
		for(int i = 1; i<= 3; i++)
        	for(int j = 1; j <= 3; j++) a[i][j] = cb[j][3 - i + 1];
		search();
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) a[i][j] = cb[i][j];
		ans.pop();
		f['B']--;
	}
	if(!f['C']){
		bz['C']++;
		f['C']++;
		ans.push('C');
		int cc[4][4];
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) cc[i][j] = a[i][j];
		swap(a[1][1] , a[1][3]) , swap(a[2][1] , a[2][3]) , swap(a[3][1] , a[3][3]);
		search();
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) a[i][j] = cc[i][j];
		ans.pop();
		f['C']--;
	}
	if(!f['D']){
		bz['D']++;
		f['D']++;
		ans.push('D');
		int cd[4][4];
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) cd[i][j] = a[i][j];
		swap(a[1][1] , a[3][1]) , swap(a[1][2] , a[3][2]) , swap(a[1][3] , a[3][3]);
		search();
		for(int i = 1; i <= 3; i++)
			for(int j = 1; j <= 3; j++) a[i][j] = cd[i][j];
		ans.pop();
		f['D']--;
	}
}
int main(){
	for(int i = 1; i <= 10; i++) eans.push('Z');
	for(int i = 1; i <= 3; i++)
		for(int j = 1; j <= 3; j++) cin >> a[i][j];
	for(int i = 1; i <= 3; i++)
		for(int j = 1; j <= 3; j++) cin >> b[i][j];
	if(pd()){	//!!!!!系列至少不为0,所以要AB一下 
		cout << "AB";
		return 0;
	}
	if(a[2][2] != b[2][2]){	//中间一直不变,中间不等相当于不可能一样 
		cout << "Poland cannot into space!!!";
		return 0;
	}
	search();
	if(!k) cout << "Poland cannot into space!!!";
	else{
		char ccc[60];
		int i = 1;
		while(!eans.empty()){
			ccc[i] = eans.top();
			eans.pop();
			i++;
		}
		for(int j = i; j >= 1; j--){
			if(ccc[j] == 'A' || ccc[j] == 'B' || ccc[j] == 'C' || ccc[j] == 'D') cout << ccc[j];
		}
	}
	return 0;
}
/*
3 4 5
6 7 8
1 2 3
1 2 3
6 7 8
3 4 5
*/

吐槽:这种大模拟/搜索是真的ex,做一次死一次orz

posted @ 2020-06-04 21:13  那一条变阻器  阅读(145)  评论(0编辑  收藏  举报