申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2011年12月1日 星期四

[最短路徑]NOIP模擬題:燃燒木棍 fire 解題報告

【問題描述】
Tom 是調皮的孩子,特別喜歡玩火,現在他手上有若干根長度分別爲 1 和sqrt(2) 的木棍,還有一張不能燃燒的平板,他把平板劃分成長度爲 1 的單元格,並標上座標。然後按以下規則把平板上的木棍組成一個連通圖:木棍的兩端必須放在單元格的頂點上。即長度爲 1 的木棍放在單元格的某一邊上,長度爲sqrt(2) 的木棍放在單元格的對角綫上。

Tom 的點火規則是,只能從木棍的兩端點火,而不能從木棍的中間點火。 如圖 ,不能在 A 點點火,但在 C 點或 B 點點火都是充許的。點火後,火會沿着木棍向前燃燒(每根都有自己的燃燒速度),並能點燃與它相接的其它木棍。
任務: 寫一程序計算從哪裏開始點火,使得燃燒的總時間最短,輸出最短時間。
Input Data
輸入文件第一行爲一個正整數 N ,表示組成圖形的木棍數目,後面共有 N 行,每行 5 個數: X1 Y1 X2 Y2 T , 其中( X1 , Y1 ) 和( X2 , Y2 )分別表示木棍兩端的座標, T 表示木棍燃燒時間,是指從木棍的某一端點火燃燒到別一端,燃完所需的時間。
Output Data
輸出文件是一個保留 4 位小數的實數,表示所有木棍完全燃燒的最少時間。
約束
1 ≤n≤40
保證圖形是連通的,所有的木棍長度都是 1 或sqrt(2) ,沒有任何兩根木棍重合 .
-200≤ X1, Y1, X2, Y2 ≤200; 0≤ T ≤ 10^7 .
如果你的輸出結果與標準答案相差小於 0.001 ,則認爲你的結果正確。
樣例 1
fire.in
1
0 0 1 1 1
fire.out
1.0000
解釋:從任一端點火都行,燃燒時間都是 1
樣例 2
fire.in5
0 0 0 1 1
1 0 0 1 10
0 0 1 0 1
0 0 1 1 1
2 2 1 1 1
fire.out 
3.2500
解釋:在 (0,0) 位置點火
木棍 1, 3 和 4 將被點燃,燃燒 0.5 分鐘後,木棍 2 將被從中間點燃向兩端燃燒,再過 0.5 分鐘,木棍 1, 3, 4 將被完全燃燒,木棍 5 將被點燃並在 1 分鐘後燃燒完 ( 比木棍 2 早燃完 ) 。
木棍 2 從中間向兩端燃燒 0.5 分鐘以後,變成兩小段,每段的燃燒時間是 4.5 分鐘。但因爲此時兩小段木棍的另一端也同時被點燃,燃燒速度變成原來的兩倍,還需 2.25 分鐘的燃燒時間, 所以總時間: 1 + 2 . 25 = 3 . 25
樣例 3
fire.in3
1 1 1 2 10
1 2 2 2 10
1 1 2 2 50
fire.out  
35.0000
解釋:在 (1,2) 位置點火, 木棍 (1 1, 1 2) 和 (1 2, 2 2) 將燃燒 10 分鐘。 . 最後一根木棍在 10 分鐘後從兩端被點燃,燃燒時間爲 25 分鐘。
【分析】
Floyd算法求最短路,只是構圖很困難罷了。
具體算法的PPT課件下載:http://zhuyifan.net84.net/ppt/fire.ppt
【我的代碼】
/*
*Problem: 燃燒木棍   fire
*Author: Yee-fan Zhu

*Date: Dec.01.2011
*Website: www.zyfworks.tk
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int N;

double max(double x,double y)
{
    if(y>x)
        x=y;
    return x;
}


class Wood
{
public:
    double x1,x2;
    double y1,y2;
    double time;
}F[42];
   
class Point
{
public:
    double x,y;
}P[1000];

Wood W[1000];
int D=0;
   
int M=0;
double Mat[1002][1002];   
int Used[2000][2000];
const int add=500;

void init()
{
    std::ios::sync_with_stdio(false);
    scanf("%d\n",&N);
    for (int i=-450;i<=1050;i++)
        for (int j=-450;j<=1050;j++)
            Used[i+add][j+add]=-1;
    for (int i=1;i<=300;i++)
        for (int j=1;j<=300;j++)
            Mat[i][j]=10000000;
    for (int i=1;i<=300;i++)
        Mat[i][i]=0;
    for (int i=1;i<=N;i++)
    {
        scanf("%lf %lf %lf %lf %lf\n",&F[i].x1,&F[i].y1,&F[i].x2,&F[i].y2,&F[i].time);
    }
    double x1,x2,y1,y2,t;
    for (int i=1;i<=N;i++)
    {
        x1=F[i].x1,y1=F[i].y1;
        x2=F[i].x2,y2=F[i].y2;
        t=F[i].time;
       
        int p1,p2;
        p1=Used[int(x1*2)+add][int(y1*2)+add];
        p2=Used[int(x2*2)+add][int(y2*2)+add];
        if(p1==-1)
        {
            M++;
            Used[int(x1*2)+add][int(y1*2)+add]=M;
            P[M].x=x1,P[M].y=y1;
            p1=M;
        }
       
        if(p2==-1)
        {
            M++;
            Used[int(x2*2)+add][int(y2*2)+add]=M;
            P[M].x=x2,P[M].y=y2;
            p2=M;
        }
       
        Mat[p1][p2]=t;
        Mat[p2][p1]=t;
        bool flag=true;
        if(F[i].x1-F[i].x2==0 || F[i].y1-F[i].y2==0)
        {
            D++;
            W[D].x1=x1,W[D].y1=y1;
            W[D].x2=x2,W[D].y2=y2;
            W[D].time=t;
            continue;
        }
        double x3,y3;
        double x4,y4;
        if((x1>x2 && y1>y2 )||(x1<x2 && y1<y2 ))
        {
            if(x1>x2 && y1>y2 )
            {
                x3=x1-1;
                y3=y1;
                x4=x1;
                y4=y1-1;
            }
            if(x1<x2 && y1<y2)
            {
                x3=x1;
                y3=y1+1;
                x4=x1+1;
                y4=y1;
            }
        }
        else
        {
            if(x1<x2 && y1>y2)
            {
                x3=x1;
                y3=y1-1;
                x4=x1+1;
                y4=y1;
            }
            if(x1>x2 && y1<y2)
            {
                x3=x1-1;
                y3=y1;
                x4=x1;
                y4=y1+1;
            }
        }
        for (int j=1;j<=N;j++)
        {
            if((F[j].x1==x3 && F[j].y1==y3 && F[j].x2==x4 &&F[j].y2==y4) || (F[j].x1==x4 && F[j].y1==y4 && F[j].x2==x3 &&F[j].y2==y3) )
            {
                double x5,y5;
                x5=double((x1+x2)/double(2));
                y5=double((y1+y2)/double(2));
                int p3=Used[int(x5*2)+add][int(y5*2)+add];
                if(p3==-1)
                {
                    M++;
                    p3=M;
                    P[M].x=x5,P[M].y=y5;
                    Used[int(x5*2)+add][int(y5*2)+add]=M;
                }
                Mat[p3][p1]=t/(double(2)),Mat[p1][p3]=t/(double(2));
                Mat[p2][p3]=t/(double(2)),Mat[p2][p3]=t/(double(2));
                D++;
                W[D].x1=x3,W[D].y1=y3;
                W[D].x2=x5,W[D].y2=y5;
                W[D].time=t/(double(2));
               
                D++;
                W[D].x1=x4,W[D].y1=y4;
                W[D].x2=x5,W[D].y2=y5;
                W[D].time=t/(double(2));
                flag=false;
                break;
            }
        }
       
        if(flag)
        {
            D++;
            W[D].x1=x1,W[D].y1=y1;
            W[D].x2=x2,W[D].y2=y2;
            W[D].time=t;
        }
    }
}

void Floyd()
{
    double tmp;
    for (int k=1;k<=M;k++)
    {
        for (int i=1;i<=M;i++)
        {
            for (int j=1;j<=M;j++)
            {
                tmp=Mat[i][k]+Mat[k][j];
                if(tmp<Mat[i][j])
                    Mat[i][j]=tmp;
            }
        }
    }
}

void work()
{
    double tot=100000000;
    for (int i=1;i<=M;i++)
    {
        double x,y;
        x=P[i].x;
        y=P[i].y;
        int tmp;
        tmp=int(x*2);
        if(tmp%2!=0)
            continue;
       
        int p=Used[int(x*2)+add][int(y*2)+add];
        double s=0;
        for (int j=1;j<=M;j++)
            s=max(s,Mat[p][j]);
       
        double x1,x2;
        double y1,y2;
        int p1,p2;
        double t1,t2;
        double dif;
        double need;
        for (int j=1;j<=D;j++)
        {
            x1=W[j].x1,y1=W[j].y1;
            x2=W[j].x2,y2=W[j].y2;
            p1=Used[int(x1*2)+add][int(y1*2)+add];
            p2=Used[int(x2*2)+add][int(y2*2)+add];
            t1=Mat[p][p1];
            t2=Mat[p][p2];
           
            double mint=t2;
            if(t1<mint)
                mint=t1;
               
            dif=max(t1-t2,t2-t1);
            if(dif>=W[j].time)
                continue;
            need=(W[j].time-dif)/(double(2));
            need=need+mint+dif;
            if(need>s)
                s=need;
        }
        if(s<tot)
            tot=s;
    }
    printf("%.4lf",tot);
}

int main()
{
    freopen("firez.in","r",stdin);
    freopen("firez.out","w",stdout);
    init();
    Floyd();
    work();
    return 0;
}


 

2011年11月28日 星期一

GZOI2011廣州NOI省選:簡易計算器 calculator 解題報告

【問題描述】相信大家都用過計算器,一般來說,計算機都可以計算簡單的加、減、乘、除這幾種運算。簡易計算器的功能和一般的計算器一樣,只是它更加簡單,只能處理整數運算,也就是說,它沒有小數點按鈕,並且它的除法運算是整除運算。現在,我們給出簡易計算器上的按鈕序列,請你編程序,模擬簡易計算器的功能,輸出最終的結果。
      
【計算器組成】簡易計算器由以下按鈕組成:數字按鈕: 0 1 2 3 4 5 6 7 8 9運算按鈕: + - * /等於號按鈕:=正負轉換按鈕:+/-為了表述方便,+/- 按鈕用 F 表示 ,
 
【計算器邏輯處理】
    
計算器內存有3個值,M1,M2,OP,STM1為計算器的左運算值,初始值為0M2為計算器的右運算值,初始值0OP為計算器的當前運算符,初始值為空ST為狀態標記,初始值為0
 
狀態裝換邏輯如下:
 
ST=0 (M1/OP輸入態):顯示值:M1
 
輸入數字N :M1=N ,轉 ST=1狀態
 
輸入F :M1=-M1,轉 ST=0狀態
 
輸入運算符:OP=運算符,轉ST=2狀態
 
輸入“=”:轉 ST=0狀態
 
ST=1 (M1+/OP輸入態):顯示值:M1
 
輸入數字N :如果M1>=0則 M1=M1*10+N 否則M1=M1*10-N;轉 ST=1狀態;
 
輸入F :M1=-M1,轉 ST=1狀態;
 
輸入運算符:OP=運算符,轉ST=2狀態
 
輸入“=”:轉 ST=0狀態
 
ST=2 (OP/M2輸入態):顯示值:M1
 
輸入數字N:M2=N,轉ST=3狀態;輸入F:M2=0,轉 ST=3狀態;
 
輸入運算符:OP=運算符,轉ST=2狀態
 
輸入“=”:
 
轉 ST=0狀態
 
ST=3 (M2+/OP輸入態):顯示值:M2
 
輸入數字N:如果M2>=0則 M2=M2*10+N 否則M2=M2*10-N;轉ST=3狀態;輸入F:M2=-M2,轉 ST=3狀態;
 
輸入運算符:M1=[M1][OP][M2] 的值OP=運算符;轉ST=2狀態
 
輸入“=”: M1=[M1][OP][M2] 的值轉ST=0狀態
 
【輸入格式】輸入只有一行,表示在計算器輸入的按鈕,長度<=100,裡面只包含如下字符 :0123456789+-*/=F輸入數據保證不會出現除以0的情況,運算過程中各個內存的值的範圍在[-10000000, 10000000] 以內

 
【輸出格式】
    
輸出包含一行整數,表示最後在計算器顯示的結果
 
【輸入樣例】
        
123=*2F-+/3+-=
        
【輸出樣例】
 
-82


 【分析】
字符串處理題目,由於各種狀態之間的來回跳換,所以用遞歸實現比較方便。由於數據不大,暴力的遞歸不成問題。

時間複雜度:O(length)。
            length表示字符串的長度。


 【我的代碼】
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
char str[102];
int OP;
int top=0;
int M1=0,M2=0;
int show;
int len;
int tmp;
void deal0();
void deal1();
void deal2();
void deal3();

int Getop(char op)
{
    if(op=='+')
        return 1;
    if(op=='-')
        return 2;
    if(op=='*')
        return 3;
    if(op=='/')
        return 4;
    if(op=='F')
        return 5;
    if(op=='=')
        return 6;
    return 0;
}

void check()
{
    if(top==len)
    {
        printf("%d\n",show);
        exit(0);
    }
    return;
}

void deal0()
{
    show=M1;
    check();
    tmp=0;
    if(Getop(str[top])==0)
    {
        while(Getop(str[top])==0 &&top<len)
        {
            tmp=tmp*10+str[top]-'0';
            top++;
        }
        M1=tmp;
        deal1();
        return;
    }
    if(Getop(str[top])==5)
    {
        M1=-M1;
        top++;
        deal0();
        return;
    }
    if(Getop(str[top])>=1 && Getop(str[top])<=4)
    {
        OP=Getop(str[top]);
        top++;
        deal2();
        return;
    }
    if(Getop(str[top])==6)
    {
        top++;
        deal0();
        return;
    }
}

void deal1()
{
    show=M1;
    check();
    tmp=0;
    if(Getop(str[top])==0)
    {
        while(Getop(str[top])==0 && top<len)
        {
            tmp=tmp*10+str[top]-'0';
            top++;
        }
        if(M1>=0)
            M1=M1*10+tmp;
        else
            M1=M1*10-tmp;
        deal1();
        return;
    }
    if(Getop(str[top])==5)
    {
        M1=-M1;
        top++;
        deal1();
        return;
    }
    if(Getop(str[top])>=1 && Getop(str[top])<=4)
    {
        OP=Getop(str[top]);
        top++;
        deal2();
        return;
    }
    if(Getop(str[top])==6)
    {
        top++;
        deal0();
        return;
    }
}

void deal2()
{
    show=M1;
    check();
    tmp=0;
    if(Getop(str[top])==0)
    {
        while(Getop(str[top])==0 && top<len)
        {
            tmp=tmp*10+str[top]-'0';
            top++;
        }
        M2=tmp;
        deal3();
        return;
    }
    if(Getop(str[top])==5)
    {
        M2=0;
        top++;
        deal3();
        return;
    }
    if(Getop(str[top])>=1 && Getop(str[top])<=4)
    {
        OP=Getop(str[top]);
        top++;
        deal2();
        return;
    }
    if(Getop(str[top])==6)
    {
        top++;
        deal0();
        return;
    }
}

void deal3()
{
    show=M2;
    check();
    tmp=0;
    if(Getop(str[top])==0)
    {
        while(Getop(str[top])==0 && top<len)
        {
            tmp=tmp*10+str[top]-'0';
            top++;
        }
        if(M2>=0)
            M2=M2*10+tmp;
        else
            M2=M2*10-tmp;
        deal3();
        return;
    }
    if(Getop(str[top])==5)
    {
        M2=-M2;
        top++;
        deal3();
        return;
    }
    if(Getop(str[top])>=1 && Getop(str[top])<=4)
    {
        if(OP==1)
            M1=M1+M2;
        if(OP==2)
            M1=M1-M2;
        if(OP==3)
            M1=M1*M2;
        if(OP==4)
            M1=M1/M2;
        OP=Getop(str[top]);
        top++;
        deal2();
        return;
    }
    if(Getop(str[top])==6)
    {
        top++;
        //deal0();
        if(OP==1)
            M1=M1+M2;
        if(OP==2)
            M1=M1-M2;
        if(OP==3)
            M1=M1*M2;
        if(OP==4)
            M1=M1/M2;
        deal0();
        return;
    }
}

void init()
{
    std::ios::sync_with_stdio(false);
    scanf("%s\n",&str);
    len=strlen(str);
    return;
}

int main()
{
    freopen("calculator.in","r",stdin);
    freopen("calculator.out","w",stdout);
    init();
    deal0();
    return 0;
}
 

 
 【評測結果】

正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 20 0.000 s 275 KB 0
2 正确 20 0.000 s 275 KB 0
3 正确 20 0.000 s 275 KB 0
4 正确 20 0.000 s 275 KB 0
5 正确 20 0.000 s 275 KB 0
运行完成
运行时间 0.002 s
平均内存使用 275 KB
测试点通过状况 AAAAA
得分:100
恭喜你通过了全部测试点!

NOIP2011提高組 選擇客棧 hotel 解題報告

【問題描述】 
麗江河邊有n 家很有特色的客棧,客棧按照其位置順序從1 到n 編號。每家客棧都按照某一種色調進行裝飾(總共k 種,用整數0 ~ k-1 表示),且每家客棧都設有一家咖啡店,每家咖啡店均有各自的最低消費。兩位遊客一起去麗江旅遊,他們喜歡相同的色調,又想嘗試兩個不同的客棧,因此決定分別住在色調相同的兩家客棧中。晚上,他們打算選擇一家咖啡店喝咖啡,要求咖啡店位於兩人住的兩家客棧之間(包括他們住的客棧),且咖啡店的最低消費不超過p。他們想知道總共有多少種選擇住宿的方案,保證晚上可以找到一家最低消費不超過p元的咖啡店小聚。

 【輸入】輸入文件hotel.in,共n+1 行。第一行三個整數n,k,p,每兩個整數之間用一個空格隔開,分別表示客棧的個數,色調的數目和能接受的最低消費的最高值;接下來的n 行,第i+1 行兩個整數,之間用一個空格隔開,分別表示i 號客棧的裝飾色調和i 號客棧的咖啡店的最低消費。

 【輸出】輸出文件名為hotel.out。輸出只有一行,一個整數,表示可選的住宿方案的總數。 

【輸入輸出樣例1】 
hotel.in 
5 2 3
 0 5 
1 3 
0 2 
1 4 
1 5 
hotel.out 

3 
【輸入輸出樣例說明】

客棧編號

色調 0 1 0 1 1
最低消費 5 3 2 4 5
2人要住同樣色調的客棧,所有可選的住宿方案包括:住客棧①③,②④,②⑤,④⑤,但是若選擇住4、5 號客棧的話,4、5 號客棧之間的咖啡店的最低消費是4,而兩人能承受的最低消費是3 元,所以不滿足要求。因此只有前3 種方案可選。 

【數據范圍】
 對於30%的數據,有n≤100; 
對於50%的數據,有n≤1,000; 
對於100%的數據,有2≤n≤200,000,0<k≤50,0≤p≤100, 0≤最低消費≤100。

【分析】
 記憶化枚舉,或者動態規劃。
可以邊讀入邊計算:
 Pre[i]:前i個客棧中,最後一個 消費小於P的客棧。
Sum[i,j]:前j個客棧中,第i種顔色的總數量。   
S:總方案數

定義ci,pi表示讀入時第i個客棧的顔色、價格。
Sum[ci,i]=Sum[ci,i-1]+1;
Sum[j,i]=Sum[j-1,i](j!=ci)
 
如果pi<=P,Pre[i]=Pre[i-1]+1,S+=Sum[ci][Pre[i]]-1。
如果pi>P,Pre[i]=Pre[i-1],S+=Sum[ci][Pre[i]]。


最後輸出S即可。沒有必要使用long long類型。

時間複雜度:O(NK)
空間複雜度:NK


【我的代碼】
C++语言: Codee#24285

01 /*
02 *Problem:NOIP2011-Senior-Hotel
03 *Date:2011.11.27
04 *Author:Yee-fan Zhu
05 */
06 #include <cstdio>
07 #include <cstdlib>
08 #include <iostream>
09 using namespace std;
10
11 const int MAXN=200002;
12 int Sum[52][MAXN];
13 int Pre[MAXN];
14 int S=0;
15 int N,P,K;
16
17 void init()
18 {
19     std::ios::sync_with_stdio(false);
20     scanf("%d %d %d\n",&N,&K,&P);
21    
22     for (int i=0;i<=N;i++)
23         Pre[i]=0;
24     for (int i=0;i<=N;i++)
25         for (int j=0;j<=K;j++)
26             Sum[j][i]=0;
27    
28     int c,p;
29     for (int i=1;i<=N;i++)
30     {
31         scanf("%d %d\n",&c,&p);
32         Sum[c][i]=Sum[c][i-1]+1;
33        
34         for (int j=0;j<K;j++)
35             if(j!=c)
36                 Sum[j][i]=Sum[j][i-1];
37        
38         if(p<=P)
39         {
40             Pre[i]=i;
41             S+=Sum[c][Pre[i]]-1;
42         }
43         else
44         {
45             Pre[i]=Pre[i-1];
46             S+=Sum[c][Pre[i]];
47         }
48     }
49     printf("%d\n",S);
50 }
51
52 int main()
53 {
54     freopen("hotel.in","r",stdin);
55     freopen("hotel.out","w",stdout);
56     init();
57     return 0;
58 }


【評測結果】
正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 41681 KB 0
2 正确 10 0.000 s 41681 KB 0
3 正确 10 0.000 s 41681 KB 0
4 正确 10 0.001 s 41681 KB 0
5 正确 10 0.001 s 41681 KB 0
6 正确 10 0.001 s 41681 KB 0
7 正确 10 0.054 s 41681 KB 0
8 正确 10 0.125 s 41681 KB 0
9 正确 10 0.192 s 41681 KB 0
10 正确 10 0.190 s 41681 KB 0
运行完成
运行时间 0.564 s
平均内存使用 41681 KB
测试点通过状况 AAAAAAAAAA
得分:100
恭喜你通过了全部测试点!
已完成数据库校验。

2011年11月27日 星期日

NOIP2011_Day1 mayan:用程序解決mayan puzzle遊戲

NOIP2011一試的第三題給我介紹了一個好玩的智力遊戲——Mayan Puzzle。聯賽過後,我從網上下載了這個一夜間變得巨火的遊戲。

在遊戲中,第9關被用來當聯賽那題的說明,第14關就是輸入輸出樣例。

遊戲下載:英文原版漢化版

首先先誇讚一下遊戲的開發人員,動畫效果做的不錯啊!

我在第8關就碰到了難題,一直過不了關,於是就用聯賽時寫的程序試了一下,結果很棒,程序總能找到正確的解決方案!於是從第8關到第45關都是我用程序解出來的~~

先貼上程序吧:
C++语言: Codee#24246
//NOIP2011-Senior-mayan
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct aaa
{
    int t[6];
    int c[6][8];
    aaa()
    {
        memset(t,0,sizeof(t));
        memset(c,0,sizeof(c));
    }
};

int n,ans[6][3];

bool flag,b[6][8];

aaa solve(aaa g)
{
    aaa h;
    int i,j;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=g.t[i];j++)
        {
            if(g.c[i][j]&&!b[i][j])
            {
                h.t[i]++;
                h.c[i][h.t[i]]=g.c[i][j];
            }
        }
    }
    return h;
}

aaa clear(aaa g)
{
    int i,j;
    aaa h;
    flag=false;
    memset(b,0,sizeof(b));
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=g.t[i];j++)
        {
            if(i<=3)
            {
                if(g.c[i][j]==g.c[i+1][j]&&g.c[i][j]==g.c[i+2][j])
                {
                    b[i][j]=b[i+1][j]=b[i+2][j]=true;
                    flag=true;
                }
            }
            if(j<=g.t[i]-2)
            {
                if(g.c[i][j]==g.c[i][j+1]&&g.c[i][j]==g.c[i][j+2])
                {
                    b[i][j]=b[i][j+1]=b[i][j+2]=true;
                    flag=true;
                }
            }
        }
    }
    if(flag)
    {
        h=solve(g);
        return clear(h);
    }
    else
    {
        return g;
    }
}

void output()
{
    freopen("mayan.out","w",stdout);
    int i;
    for(i=1;i<=n;i++)
    {
        printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
    }
    exit(0);
}

void dfs(aaa g,int k)
{
    int i,j,l;
    aaa h;
    flag=true;
    for(i=1;i<=5;i++)
    {
        if(g.t[i])
        {
            flag=false;
            break;
        }
    }
    if(flag)
    {
        if(k>n)
        {
            output();
        }
        else
        {
            return;
        }
    }
    if(k>n)
    {
        return;
    }
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=g.t[i];j++)
        {
            if(i<5)
            {
                if(j>g.t[i+1])
                {
                    h=g;
                    h.t[i+1]++;
                    h.c[i+1][h.t[i+1]]=h.c[i][j];
                    h.c[i][j]=0;
                    h.t[i]--;
                    for(l=j;l<=h.t[i];l++)
                    {
                        h.c[i][l]=h.c[i][l+1];
                    }
                    h=clear(h);
                    ans[k][0]=i-1;
                    ans[k][1]=j-1;
                    ans[k][2]=1;
                    dfs(h,k+1);
                }
                else
                {
                    h=g;
                    l=h.c[i][j];
                    h.c[i][j]=h.c[i+1][j];
                    h.c[i+1][j]=l;
                    h=clear(h);
                    ans[k][0]=i-1;
                    ans[k][1]=j-1;
                    ans[k][2]=1;
                    dfs(h,k+1);
                }
            }
            if(i>1)
            {
                if(j>g.t[i-1])
                {
                    h=g;
                    h.t[i-1]++;
                    h.c[i-1][h.t[i-1]]=h.c[i][j];
                    h.c[i][j]=0;
                    h.t[i]--;
                    for(l=j;l<=h.t[i];l++)
                    {
                        h.c[i][l]=h.c[i][l+1];
                    }
                    h=clear(h);
                    ans[k][0]=i-1;
                    ans[k][1]=j-1;
                    ans[k][2]=-1;
                    dfs(h,k+1);
                }
            }
        }
    }
}

int main()
{
    freopen("mayan.in","r",stdin);
    freopen("mayan.out","w",stdout);
    int i,j;
    aaa g;
    scanf("%d",&n);
    for(i=1;i<=5;i++)
    {
        scanf("%d",&j);
        while(j)
        {
            g.t[i]++;
            g.c[i][g.t[i]]=j;
            scanf("%d",&j);
        }
    }
    dfs(g,1);
    printf("-1\n");
    return 0;
}

比如第10關,把它轉換為程序的輸入文件就是這樣:
mayan.in
3
1 2 2 0
2 0
1 0
3 1 3 0
1 3 1 0

運行程序,輸出文件是:
mayan.out
0 0 1
3 2 1
3 0 1

於是我按照程序的“指示”移動方塊,沒想到果然過關了!