IOI1994 北京2008的挂钟 迭代加深

总的来讲,这是一道很⑨的题,因为:

(1)题目中有⑨个挂钟

(2)有⑨种操作方案

(3)这题因为解空间太小所以可以直接⑨重循环!!

这题可以用迭代加深搜索高效求解,剪枝的策略也很显然:

>所求的操作序列一定是单调不递减的

>同一操作不可能在解中出现4次及以上(操作4次等于没有操作)

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5 using namespace std;
 6
 7 int dir[10]={0};
 8 int cmdCnt[10]={0};
 9 int ans[10]={0};
10
11 void move(int _cmd)
12 {
13     ++cmdCnt[_cmd];
14
15     switch(_cmd)
16     {
17     case 1: ++dir[1]; ++dir[2]; ++dir[4]; ++dir[5]; break;
18     case 2: ++dir[1]; ++dir[2]; ++dir[3]; break;
19     case 3: ++dir[2]; ++dir[3]; ++dir[5]; ++dir[6]; break;
20     case 4: ++dir[1]; ++dir[4]; ++dir[7]; break;
21     case 5: ++dir[2]; ++dir[4]; ++dir[5]; ++dir[6]; ++dir[8]; break;
22     case 6: ++dir[3]; ++dir[6]; ++dir[9]; break;
23     case 7: ++dir[4]; ++dir[5]; ++dir[7]; ++dir[8]; break;
24     case 8: ++dir[7]; ++dir[8]; ++dir[9]; break;
25     case 9: ++dir[5]; ++dir[6]; ++dir[8]; ++dir[9]; break;
26     }
27 }
28
29 void undo(int _cmd)
30 {
31     --cmdCnt[_cmd];
32
33     switch(_cmd)
34     {
35     case 1: --dir[1]; --dir[2]; --dir[4]; --dir[5]; break;
36     case 2: --dir[1]; --dir[2]; --dir[3]; break;
37     case 3: --dir[2]; --dir[3]; --dir[5]; --dir[6]; break;
38     case 4: --dir[1]; --dir[4]; --dir[7]; break;
39     case 5: --dir[2]; --dir[4]; --dir[5]; --dir[6]; --dir[8]; break;
40     case 6: --dir[3]; --dir[6]; --dir[9]; break;
41     case 7: --dir[4]; --dir[5]; --dir[7]; --dir[8]; break;
42     case 8: --dir[7]; --dir[8]; --dir[9]; break;
43     case 9: --dir[5]; --dir[6]; --dir[8]; --dir[9]; break;
44     }
45 }
46
47 inline bool isDest()
48 {
49     for(int i=1;i<=9;i++) if(dir[i] & 3) return false;
50     return true;
51 }
52
53 bool search_aux(int _maxDepth,int _curDepth,int _lastCmd)
54 {
55     if(isDest()) return true;
56     if(_curDepth > _maxDepth) return false;
57
58     for(int i=_lastCmd;i<=9;i++)
59     {
60         if(cmdCnt[i] < 3)
61         {
62             move(i);
63             bool next=search_aux(_maxDepth,_curDepth+1,i);
64             undo(i);
65             if(next) { ++ans[i]; return true; }
66         }
67     }
68
69     return false;
70 }
71
72 void input()
73 {
74     for(int i=1;i<=9;i++) scanf("%d",dir+i);
75 }
76
77 void search()
78 {
79     for(int i=1;;i++) if(search_aux(i,1,1)) return;
80 }
81
82 void printAns()
83 {
84     for(int i=1;i<=9;i++)
85         while(ans[i]--) printf("%d ",i);
86 }
87
88 int main()
89 {
90     input();
91     search();
92     printAns();
93     return 0;
94 }

Cirno is willing to try this problem (*^__^*)

时间: 2024-11-08 23:10:55

IOI1994 北京2008的挂钟 迭代加深的相关文章

vijos 1016 北京2008的挂钟

北京2008的挂钟 描述 在2008北京奥运会雄伟的主会场的墙上,挂着如上图所示的3*3的九个挂钟(一开始指针即时针指向的位置请根据输入数据调整).然而此次奥运会给与了大家一个机会,去用最少的移动操作改变上面的挂钟的时间全部为12点正(我们只考虑时针).然而每一次操作并不是任意的,我们必须按照下面给出的列表对于挂钟进行改变.每一次操作我们给而且必须给指定的操作挂钟进行,每一个挂钟顺时针转动90度.列表如下: 操作 指定的操作挂钟1 ABDE2 ABC3 BCEF4 ADG5 BDEFH6 CFI

Vijos——T 1016 北京2008的挂钟 || 洛谷—— P1213 时钟

https://www.luogu.org/problem/show?pid=1213 题目描述 考虑将如此安排在一个 3 x 3 行列中的九个时钟: 目标要找一个最小的移动顺序将所有的指针指向12点.下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动.选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度. 移动方法 受影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI Example

poj 3134 Power Calculus(迭代加深dfs+强剪枝)

Description Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications: x2 = x × x, x3 = x2 × x, x4 = x3 × x, …, x31 = x30 × x. The operation of squaring can be appreciably shorten the sequence of multiplications.

[poj 2331] Water pipe ID A*迭代加深搜索(dfs)

Water pipe Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2265 Accepted: 602 Description The Eastowner city is perpetually haunted with water supply shortages, so in order to remedy this problem a new water-pipe has been built. Builders s

UVA 10160 Servicing Stations(状态压缩+迭代加深)

[题目链接] LInk [题目大意] 给出一些点和边,选择一个点就能把这个点和相邻的点都覆盖,求最小点覆盖 [题解] 我们压缩点被覆盖的状态,迭代加深搜索覆盖的最小点数, 当剩余的点全部选上时都无法完全覆盖就剪枝. [代码] #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int N=36; int i,n,m,x,y,limit; LL st[N],Lf

UVA-11214 Guarding the Chessboard (迭代加深搜索)

题目大意:在一个国际象棋盘上放置皇后,使得目标全部被占领,求最少的皇后个数. 题目分析:迭代加深搜索,否则超时. 小技巧:用vis[0][r].vis[1][c].vis[2][r+c].vis[c-r+N]分别标志(r,c)位置相对应的行.列.主.副对角线有没有被占领(详见<入门经典(第2版)>P193),其中N表示任意一个比行数和列数都大(大于等于)的数. 代码如下: # include<iostream> # include<cstdio> # include&l

USACO/fence8 迭代加深搜索+剪枝

题目链接 迭代加深搜索思想. 枚举答案K,考虑到能否切出K个木头,那么我们当然选最小的K个来切. 1.对于原材料,我们是首选最大的还是最小的?显然,首选大的能够更容易切出,也更容易得到答案. 2.对于目标木头,我们是优先得到最大的还是最小的?显然,由于K个木头我们都要得到,那么当然先把最大的(最难得到的)先得到,这种搜索策略更优. 3.假设总原材料为all,前K个木头总和为sum,那么all-sum就是这一次切割过程中能[浪费]的最大数目.对于一个切剩下的原材料,若它比最小的目标木头还要小,则它

hdu 1560 DNA sequence(迭代加深搜索)

DNA sequence Time Limit : 15000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 15   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description The twenty-first century

1374 - Power Calculus (迭代加深+剪枝)

题目要求乘除法的最少次数,其实就是一个数组中一开始只有一个数:1 ,每次可以从数组中取两个数(可以取同一个数)相加生成一个新数加如数组 . 那么显然这是一个迭代加深搜索,从小到大枚举深度上限 . 为了降低时间复杂度,我们要尽量的减少迭代次数,所以我们优先做加法,并且优先将最大的两个数相加,这样可以最快的接近目标 . 当然,有一个很显然的剪枝: 当每次取最大的两个数相加仍然小于n时要剪枝 .因为以最快的方式增长的话其指数是按照2的幂次增加的,所以当前最大值maxv*pow(2,maxd-d) <