打卡信奥刷题(2403)用C++实现信奥 P1213 [IOI 1994 / USACO1.4] 时钟 The Clocks

P1213 [IOI 1994 / USACO1.4] 时钟 The Clocks

题目描述

考虑将如此安排在一个 3×33 \times 33×3 行列中的九个时钟:

|-------|   |-------|   |-------|
|       |   |       |   |   |   |
|---o   |   |---o   |   |   o   |
|       |   |       |   |       |
|-------|   |-------|   |-------|
    A           B           C

|-------|   |-------|   |-------|
|       |   |       |   |       |
|   o   |   |   o   |   |   o   |
|   |   |   |   |   |   |   |   |
|-------|   |-------|   |-------|
    D           E           F

|-------|   |-------|   |-------|
|       |   |       |   |       |
|   o   |   |   o---|   |   o   |
|   |   |   |       |   |   |   |
|-------|   |-------|   |-------|
    G           H           I

目标要找一个最小的移动顺序将所有的指针指向 121212 点。下面的表格列出了 999 种不同的旋转指针的方法,每一种方法都叫一次移动,选择 1∼91 \sim 919 号移动方法,将会使在表格中对应的时钟的指针顺时针旋转
909090 度。

移动方法受影响的时钟
1ABDE
2ABC
3BCEF
4ADG
5BDEFH
6CFI
7DEGH
8GHI
9EFHI

例如:

9 9 12       9 12 12        9 12 12        12 12 12        12 12 12
6 6 6   5 -> 9  9  9   8 -> 9  9  9   4 -> 12  9  9   9 -> 12 12 12
6 3 6        6  6  6        9  9  9        12  9  9        12 12 12

但这可能不是正确的方法,请看下文。

输入格式

输入三行,每行三个正整数,表示一个时钟的初始时间(样例中数字的含义和上面 d 的例子一样)。

输出格式

单独的一行包括一个用空格分开的将所有指针指向 121212 点的最短移动顺序的列表。

如果有多种方案,输出字典序最小的方案。(例如 5 2 4 6 的字典序小于 9 3 1 1)。

输入输出样例 #1

输入 #1

9 9 12
6 6 6
6 3 6

输出 #1

4 5 8 9

说明/提示

题目翻译来自 NOCOW。

USACO Training Section 1.4

C++实现

#include<iostream>
#define M 9//3*3 
using namespace std;
int node[M][M]={
{1,1,0,1,1,0,0,0,0},
{1,1,1,0,0,0,0,0,0},
{0,1,1,0,1,1,0,0,0},
{1,0,0,1,0,0,1,0,0},
{0,1,0,1,1,1,0,1,0},
{0,0,1,0,0,1,0,0,1},
{0,0,0,1,1,0,1,1,0},
{0,0,0,0,0,0,1,1,1},
{0,0,0,0,1,1,0,1,1}
};
int a[M],c[M],f[M];
void dfs(int x);
int main()
{
	for(int i=0;i<M;i++)
	{
		cin>>a[i];
		a[i]=a[i]/3%4;//用0-4来表示12,3,6,9点 
	}//
	dfs(0);//开始深搜 
	return 0;
}
void dfs(int x){
	bool ok=1;//由于判断是否符合条件:全变为12点 
	for(int i=0;i<M;i++)f[i]=a[i];//复制 
	for(int i=0;i<M;i++)
		for(int j=0;j<M;j++)f[i]=(f[i]+node[j][i]*c[j])%4;//循环进行取数,并模4取余 
	for(int i=0;i<M;i++)
		if(f[i]>0){ok=0;break;} //只有全为0,即全是12点才可以 
	if(ok){
		for(int i=0;i<M;i++)
			for(int j=0;j<c[i];j++)cout<<i+1<<" ";//数组从0开始的原因才要i+1 
		cout<<endl;
		x=9;//相当于return; (让它变为边界数) 
	}
	if(x==M)return;//边界条件 
	for(int i=0;i<4;i++){c[x]=i;dfs(x+1);} //继续进行搜索(0-3即可) 
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值