CF 887C Solution for Cuble 魔方,暴力

本文介绍了一种2x2x2魔方的平面展开图通过六种旋转方式判断是否能一次性复原的算法实现。通过具体的C++代码示例详细展示了每种旋转对应的魔方状态变化及验证复原条件。
题意:给出2*2*2魔方的平面展开图 每个格子按照题意编号为[1..24] 
现在给出a[i]表示第i个格子的颜色 问是否能通过旋转一次魔方 使得魔方复原


2*2*2旋转的方案 一共只有6种 (上层顺时针等价于下层逆时针)

每一种相当于一个置换 暴力写出每一种情况即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+5;
int n=24,a[N],b[N];
bool check()
{
	bool flag=true;
	for(int i=1;i<=n;i+=4)
	{
		int x=a[i];
		for(int j=i+1;j<=i+3;j++)
			if(x!=a[j])
				flag=false;
	}
	for(int i=1;i<=n;i++)
		a[i]=b[i];
	if(flag)
	{
		puts("YES");
		exit(0);
	}
}
void UF()
{
	a[2]=b[6],a[4]=b[8];
	a[21]=b[4],a[23]=b[2];
	a[12]=b[21],a[10]=b[23];
	a[6]=b[12],a[8]=b[10];
	check();
}
void UB()
{
	a[6]=b[2],a[8]=b[4];
	a[12]=b[8],a[10]=b[6];
	a[21]=b[12],a[23]=b[10];
	a[2]=b[23],a[4]=b[21];
	check();
}
void RC()
{
	a[18]=b[12],a[20]=b[11];
	a[1]=b[18],a[2]=b[20];
	a[15]=b[1],a[13]=b[2];
	a[12]=b[15],a[11]=b[13];
	check();
}
void LC()
{
	a[13]=b[11],a[15]=b[12];
	a[1]=b[15],a[2]=b[13];
	a[18]=b[1],a[20]=b[2];
	a[12]=b[18],a[11]=b[20];
	check();
}
void One()
{
	a[23]=b[16],a[24]=b[15];
	a[20]=b[23],a[19]=b[24];
	a[8]=b[20],a[7]=b[19];
	a[16]=b[8],a[15]=b[7];
	check();
}
void Two()
{
	a[15]=b[24],a[16]=b[23];
	a[7]=b[15],a[8]=b[16];
	a[19]=b[7],a[20]=b[8];
	a[23]=b[20],a[24]=b[19];

	check();
}
int main()
{
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),b[i]=a[i];
	UF(); 
	UB();
	RC();
	LC();
	One();
	Two();
	
	puts("NO");
	return 0;
}


标程:

#include <bits/stdc++.h>
       
using namespace std;
       
typedef long long ll;
#define mp make_pair
#define pub push_back
#define x first
#define y second
#define all(a) a.begin(), a.end()
#define db double
 
int a[25];
 
void rotate(vector<int> q){
    for (int it = 0; it < 2; it++){
        int tmp = a[q[0]];
        for (int i = 1; i < q.size(); i++) a[q[i - 1]] = a[q[i]];
        a[q.back()] = tmp;
    }
}
 
void move(int type){
    if (type == 0) rotate({1, 3, 5, 7, 9, 11, 24, 22});
    if (type == 1) rotate({2, 4, 6, 8, 10, 12, 23, 21});
    if (type == 2) rotate({9, 10, 19, 17, 4, 3, 14, 16});
    if (type == 3) rotate({11, 12, 20, 18, 2, 1, 13, 15});
    if (type == 4) rotate({13, 14, 5, 6, 17, 18, 21, 22});
    if (type == 5) rotate({15, 16, 7, 8, 19, 20, 23, 24});
}
 
bool ok(vector<int> q){
    int cc = a[q[0]];
    for (int to : q) if (a[to] != cc) return 0;
    return 1;
}
 
bool check(){
    return ok({1, 2, 3, 4}) && ok({5, 6, 7, 8}) && ok({9, 10, 11, 12}) && ok({13, 14, 15, 16}) && ok({21, 22, 23, 24});
}
 
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    for (int i = 1; i <= 24; i++) cin >> a[i]; 
   
    for (int i = 0; i < 6; i++){
        move(i);
        if (check()) cout << "YES", exit(0);
        move(i); move(i);
        if (check()) cout << "YES", exit(0);
        move(i);
    }
 
    cout << "NO";
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值