poj2965-poj2965-The Pilots Brothers' refrigerator
生活随笔
收集整理的這篇文章主要介紹了
poj2965-poj2965-The Pilots Brothers' refrigerator
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
方法同poj1753,但用在這題就TLE了,以下是TLE版本:
Code
??1#include?<stdio.h>
??2#include?<stdlib.h>
??3#include?<string.h>
??4#define?MAXSTATE?65536
??5#define?MAXSIZE?16
??6#define?ALLOPEN?0
??7
??8//隊列結構體
??9typedef?struct?node{
?10????int?data;
?11????struct?node?*next;
?12}NODE;
?13typedef?struct{
?14????NODE?*front;
?15????NODE?*rear;
?16}QUEUE;
?17//全局變量
?18QUEUE?queue;
?19int?distance[MAXSTATE];
?20int?position[MAXSTATE];
?21int?parentState[MAXSTATE];
?22//入隊列函數
?23void?EnQueue(QUEUE?*q,?int?d)
?24{
?25????NODE?*newNode;
?26????newNode=(NODE?*)malloc(sizeof(NODE));
?27????newNode->data=d;
?28????newNode->next=NULL;
?29????
?30????if(q->front!=NULL){
?31????????q->rear->next=newNode;
?32????????q->rear=newNode;
?33????}
?34????else
?35????????q->front=q->rear=newNode;
?36}
?37//出隊列函數
?38int?DeQueue(QUEUE?*q)
?39{
?40????int?temp;
?41????NODE?*oldNode;
?42????if(q->front==NULL){
?43????????printf("List?empty!\n");
?44????????return?-1;
?45????}
?46????oldNode=q->front;
?47????temp=q->front->data;
?48????q->front=q->front->next;
?49????free(oldNode);
?50????return?temp;
?51}
?52//判斷隊列是否為空
?53int?Empty(QUEUE?*q){
?54????if(q->front==NULL)
?55????????return?1;
?56????return?0;
?57}
?58
?59int?ChangeState(int?id,?int?pos)
?60{
?61????int?t,?new_id;
?62????new_id=id^1<<pos;
?63????if?(pos>=4){
?64????????t=pos-4;
?65????????while(t>=0)?{
?66????????????new_id^=1<<t;
?67????????????t-=4;
?68????????}
?69????}
?70????if(pos<=11){
?71????????t=pos+4;
?72????????while(t<=15){
?73????????????new_id^=1<<t;
?74????????????t+=4;
?75????????}
?76????}
?77????if(pos%4>0){//向左
?78????????t=pos-1;
?79????????while(t%4!=3?&&?t>=0){
?80????????????new_id^=1<<t;
?81????????????--t;
?82????????}
?83????}
?84????if(pos%4<3){//向右
?85????????t=pos+1;
?86????????while(t%4!=0){
?87????????????new_id^=1<<t;
?88????????????++t;
?89????????}
?90????}
?91????return?new_id;
?92}
?93
?94void?Output(int?stat)
?95{
?96????int?cur_state,?len=0,?i;
?97????int?arr_x[MAXSIZE];
?98????int?arr_y[MAXSIZE];
?99????
100????cur_state=stat;
101????printf("%d\n",?distance[cur_state]);
102????while(distance[cur_state]!=0){
103????????arr_x[len]=position[cur_state]/4+1;
104????????arr_y[len++]=position[cur_state]%4+1;
105????????cur_state=parentState[cur_state];
106????}
107????for?(i=len-1;i>=0;i--){
108????????printf("%d?%d\n",?arr_x[i],?arr_y[i]);
109????}
110}
111
112void?main(int?argc,?char?*argv[])
113{
114????char?c;
115????int?cur_state=0,?new_state;
116????int?i=0;
117????QUEUE?*q;
118????q=&queue;
119????//freopen("input.txt",?"r",?stdin);
120????
121????while(scanf("%c",?&c)!=EOF){
122????????if(c!='\n'){
123????????????if?(c=='+')?cur_state?+=?1<<i;
124????????????i++;
125????????}
126????}
127????memset(distance,?-1,?MAXSTATE*sizeof(int));
128????
129????if(cur_state==ALLOPEN){
130????????printf("0\n");
131????????return;
132????}
133????parentState[cur_state]=-1;
134????distance[cur_state]=0;
135????position[cur_state]=-1;
136????EnQueue(q,?cur_state);
137????while(!Empty(q)){
138????????cur_state=DeQueue(q);
139????????for?(i=0;i<MAXSIZE;i++){
140????????????new_state=ChangeState(cur_state,?i);
141????????????if?(new_state==ALLOPEN){//成功
142????????????????parentState[new_state]=cur_state;
143????????????????position[new_state]=i;
144????????????????distance[new_state]=distance[cur_state]+1;
145????????????????Output(new_state);
146????????????????return;
147????????????}
148????????????if?(distance[new_state]==-1){//未訪問過結點
149????????????????distance[new_state]=distance[cur_state]+1;
150????????????????position[new_state]=i;
151????????????????parentState[new_state]=cur_state;
152????????????????EnQueue(q,?new_state);
153????????????}
154????????}
155????}
156}
?
?優化過程:將需要改變的狀態存放在一個一維數組當中,這樣就減少了每次改變狀態時的開銷。如下所示:
int state[MAXSIZE]={
0xF888,0xF444,0xF222,0xF111,
0x8F88,0x4F44,0x2F22,0x1F11,
0x88F8,0x44F4,0x22F2,0x11F1,
0x888F,0x444F,0x222F,0x111F};
?0xF888轉換為二進制是1111 1000 1000 1000,換一種格式:
1111
1000
1000
1000
表示改變坐標(0,0)的狀態時第一列和第一行的狀態都要改變,這樣只要和當前狀態XOR一下就可以得到新的狀態了。
再次提交了一次任然是TLE。。。看來效果不是很明顯。
繼續改進,發現隊列用的是鏈表實現,效率沒有用數組高,因而將鏈表用數組全部重寫。
再次提交,果然AC了。
| Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
| 4856540 | zen_chou | 2965 | Accepted | 1220K | 219MS | C | 2387B | 2009-03-26 17:27:36 |
?
Code??1#include?<stdio.h>
??2#include?<stdlib.h>
??3#include?<string.h>
??4#define?MAXSTATE?65536
??5#define?MAXSIZE?16
??6#define?ALLOPEN?0
??7//循環隊列結構體
??8typedef?struct{
??9????int?head,?tail;
?10????int?node[MAXSTATE];
?11}QUEUE;
?12//隊列函數
?13void?Init(QUEUE?*q)
?14{
?15????q->head=q->tail=0;
?16}
?17int?Empty(QUEUE?*q)
?18{
?19????if?((q->head-q->tail)==0)?return?1;
?20????return?0;
?21}
?22void?EnQueue(QUEUE?*q?,int?d)
?23{
?24????if?((q->tail+1)%MAXSTATE==q->head){
?25????????printf("Overflow!\n");
?26????????return;
?27????}
?28????q->node[q->tail]=d;
?29????q->tail=(q->tail+1)%MAXSTATE;
?30}
?31int?DeQueue(QUEUE?*q)
?32{
?33????int?d;
?34????if?(q->head==q->tail)?{
?35????????printf("Underflow!\n");
?36????????return?-1;
?37????}
?38????d=q->node[q->head];
?39????q->head=(q->head+1)%MAXSTATE;
?40????return?d;
?41}
?42//全局變量
?43int?distance[MAXSTATE];
?44int?position[MAXSTATE];
?45int?parentState[MAXSTATE];
?46QUEUE?queue;
?47int?state[MAXSIZE]={
?480xF888,0xF444,0xF222,0xF111,
?490x8F88,0x4F44,0x2F22,0x1F11,
?500x88F8,0x44F4,0x22F2,0x11F1,
?510x888F,0x444F,0x222F,0x111F};
?52
?53
?54int?ChangeState(int?id,?int?pos)
?55{
?56????int?new_id;
?57????new_id=id^state[pos];
?58????return?new_id;
?59}
?60
?61void?Output(int?stat)
?62{
?63????int?cur_state,?len=0,?i;
?64????int?arr_x[MAXSIZE];
?65????int?arr_y[MAXSIZE];
?66????cur_state=stat;
?67????printf("%d\n",?distance[cur_state]);
?68????while(distance[cur_state]!=0){
?69????????arr_x[len]=position[cur_state]/4+1;
?70????????arr_y[len++]=position[cur_state]%4+1;
?71????????cur_state=parentState[cur_state];
?72????}
?73????for?(i=len-1;i>=0;i--){
?74????????printf("%d?%d\n",?arr_x[i],?arr_y[i]);
?75????}
?76}
?77
?78void?main(int?argc,?char?*argv[])
?79{
?80????char?c;
?81????int?cur_state=0,?new_state;
?82????int?i=0;
?83????QUEUE?*q;
?84????q=&queue;
?85????//freopen("input.txt",?"r",?stdin);
?86????
?87????while(scanf("%c",?&c)!=EOF){
?88????????if(c!='\n'){
?89????????????cur_state<<=1;
?90????????????if?(c=='+')?cur_state+=1;
?91????????}
?92????}
?93????memset(distance,?-1,?MAXSTATE*sizeof(int));
?94????
?95????if(cur_state==ALLOPEN){
?96????????printf("0\n");
?97????????return;
?98????}
?99????parentState[cur_state]=-1;
100????distance[cur_state]=0;
101????position[cur_state]=-1;
102????EnQueue(q,?cur_state);
103????while(!Empty(q)){
104????????cur_state=DeQueue(q);
105????????for?(i=0;i<MAXSIZE;i++){
106????????????new_state=ChangeState(cur_state,?i);
107????????????if?(new_state==ALLOPEN){//成功
108????????????????parentState[new_state]=cur_state;
109????????????????position[new_state]=i;
110????????????????distance[new_state]=distance[cur_state]+1;
111????????????????Output(new_state);
112????????????????return;
113????????????}
114????????????if?(distance[new_state]==-1){//未訪問過結點
115????????????????distance[new_state]=distance[cur_state]+1;
116????????????????position[new_state]=i;
117????????????????parentState[new_state]=cur_state;
118????????????????EnQueue(q,?new_state);
119????????????}
120????????}
121????}
122}
轉載于:https://www.cnblogs.com/zen_chou/archive/2009/03/26/1422148.html
總結
以上是生活随笔為你收集整理的poj2965-poj2965-The Pilots Brothers' refrigerator的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再给我两分钟是哪首歌啊?
- 下一篇: 求一个好听的微信公众号名字!