1. 程式人生 > >洛谷 P1213 時鐘 &&IOI 1994 The Clocks

洛谷 P1213 時鐘 &&IOI 1994 The Clocks

push print char* pre 不同 方法 aps 壓力 那種

IOI 1994 The Clocks

題目描述

考慮將如此安排在一個 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

技術分享

[但這可能不是正確的方法,請看下面]

輸入輸出格式

輸入格式:

第1-3行: 三個空格分開的數字,每個數字表示一個時鐘的初始時間,3,6,9,12。數字的含意和上面第一個例子一樣。

輸出格式:

單獨的一行包括一個用空格分開的將所有指針指向12:00的最短移動順序的列表。

如果有多種方案,輸出那種使其連接起來數字最小的方案。(舉例來說5 2 4 6 < 9 3 1 1)。

輸入輸出樣例

輸入樣例#1:
9 9 12
6 6 6
6 3 6 
輸出樣例#1:
4 5 8 9

說明

題目翻譯來自NOCOW。

USACO Training Section 1.4

暴力bfs 在vijos 上是可以A的

但是在洛谷 會被卡掉兩個點 1.3s 死活沒法再優化了

若有會的dalao 幫幫我

換dfs

每一種變換 最多變3次 第四次就回到原來的狀態

所以我們可以dfs每一種變換方式的次數 最多三次

bfs超時數據 dfs 0.1s毫無壓力

#include <queue>
#include <ctime>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>

/*int z[9][9]={{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 z[10][10] = {{0},{1,2,4,5},{1,2,3},{2,3,5,6},{1,4,7},{2,4,5,6,8},
                  {3,6,9},{4,5,7,8},{7,8,9},{5,6,8,9}};

int s[10];

struct node {
	int s[10];
	int cnt;
	int path[100];
	friend bool operator < (node x,node y) {
		return x.cnt>y.cnt;
	}
};
node a,now,t;

bool f[4][4][4][4][4][4][4][4][4];

inline void read(int&x) {
	register char c=getchar();
	for(x=0;!isdigit(c);c=getchar());
	for(;isdigit(c);x=x*10+c-48,c=getchar());
}

inline bool pd(int*p) {
	for(int i=0;i<9;++i) if(p[i]) return false;
	return true;
}

inline bool check(int*p) {
	if(f[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]]) return false;
	f[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]]=1;
	return true; 
}

inline void BFS() {
	std::priority_queue<node> q;
	memcpy(a.s,s,sizeof s);
	q.push(a);
	while(!q.empty()) {
		now=q.top();
		q.pop();
		for(int i=1;i<=9;++i) {
			t=now;
			if(pd(now.s)) {
				std::sort(now.path+1,now.path+now.cnt+1);
				for(int k=1;k<=now.cnt;++k) printf("%d ",now.path[k]);
				return;
			}
			for(int j=0;z[i][j];++j) {
				++t.s[z[i][j]-1];
				if(t.s[z[i][j]-1]>=4) t.s[z[i][j]-1]-=4;
			}
			if(check(t.s)) {
				t.path[++t.cnt]=i;
				q.push(t);
			}	
		}
	}
	return;
}

int hh() {
	freopen("1.out","r",stdin);
	int t=clock();
	for(int x,i=0;i<9;++i)
	   read(x),x=(x/3)%4,s[i]=x;//
	f[s[0]][s[1]][s[2]][s[3]][s[4]][s[5]][s[6]][s[7]][s[8]]=1;
	BFS();
	printf("%d\n",clock());
	return 0;
}

int sb=hh();
int main(int argc,char**argv) {;}

  

#include <queue>
#include <ctime>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>

const int MAXN=10;

int z[9][9]={{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 s[MAXN],tmp[MAXN],ans[MAXN];

inline void read(int&x) {
	register char c=getchar();
	for(x=0;!isdigit(c);c=getchar());
	for(;isdigit(c);x=x*10+c-48,c=getchar());
}

inline bool check() {
	for(int i=0;i<9;++i) if(tmp[i]) return false;
	return true;
}

inline void print() {
	for(int i=0;i<9;++i)
	  for(int j=0;j<ans[i];++j)
	    printf("%d ",i+1);
	exit(0);
}

inline void DFS(int step) {
	memcpy(&tmp,&s,sizeof tmp);
	for(int i=0;i<9;++i)
	  for(int j=0;j<9;++j)
	    tmp[i]=(tmp[i]+z[j][i]*ans[j])%4;
	if(check()) {print();}
	if(step==9) return;
	for(int i=0;i<4;++i)
	  ans[step]=i,DFS(step+1);	  
	return;
}

int hh() {
//	freopen("1.out","r",stdin);
//	int t=clock();
	for(int x,i=0;i<9;++i)
	   read(x),x=(x/3)%4,s[i]=x;
	DFS(0);
//	printf("%d\n",clock());
	return 0;
}

int sb=hh();
int main(int argc,char**argv) {;}

  

洛谷 P1213 時鐘 &&IOI 1994 The Clocks