求一堆積木依照指令堆疊之後,最後的排列情形

[心得]

1. map[][] 儲存各個位置的積木編號,沒有積木的位置用-1表示

2. loc[] 儲存該編號的積木所在之行、end[] 表示該行最後一個積木的高度 (沒有為-1)

3.放回寫成函式back(),需要再呼叫即可,全域變數記得擺在最前面

4.每個動作都要考慮到 map、loc、end,改變的次序很重要,以及先用其他變數記錄

5. continue 的作用是回到迴圈起始點重新開始,可以用在不做任何改變的情況

 

#include <stdio.h>
#include <string.h>

    int n,i,j,k,a,b,map[25][25]; /* the blocks' number in map */
    int loc[25],end[25]; /* the height of loc[a] */

void back(int a)
{
     int h,t;
    
     for(h=end[loc[a]];map[loc[a]][h]!=a;h--)
     {
         map[map[loc[a]][h]][end[map[loc[a]][h]]+1]=map[loc[a]][h]; /* the number */
         loc[map[loc[a]][h]]=map[loc[a]][h]; /* the location */
         end[map[loc[a]][h]]++; /* the height */
         map[loc[a]][h]=-1;
         end[loc[a]]--;
     }
}

void pile_over(int a,int b)
{   
     int h,last,t1,t2,t3; /* the amount of blocks under a */
    
     for(h=0;h<n;h++)
         if(map[loc[a]][h]==a) /* get the height of a */
             break;
     last=end[loc[a]]-h;
     t1=end[loc[a]];
     t2=end[loc[b]];
     t3=loc[a];
     end[loc[a]]=end[loc[a]]-(last+1);
     end[loc[b]]=end[loc[b]]+(last+1);
    
     for(i=0,j=1;i<=last;i++,j++)
     {
         map[loc[b]][t2+j]=map[t3][h+i];
         loc[map[t3][h+i]]=loc[b];
         map[t3][h+i]=-1;
     }
}

void move_onto(int a,int b)
{
     back(a); back(b);
     pile_over(a,b);
}
void move_over(int a,int b)
{
     back(a);
     pile_over(a,b);
}
void pile_onto(int a,int b)
{
     back(b);
     pile_over(a,b);
}

int main()
{
    char str1[5],str2[5];
   
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            for(j=1;j<n;j++)
                map[i][j]=-1;
            map[i][0]=i;
            loc[i]=i;
            end[i]=0;
        }
       
        while(scanf("%s",str1))
        {
            if(!strcmp(str1,"quit"))
                break;
            scanf("%d %s %d",&a,str2,&b);
            if((a==b)||(loc[a]==loc[b]))
                continue; /* back to the start of while */
           
            if(!strcmp(str1,"move"))
                if(!strcmp(str2,"onto"))
                    move_onto(a,b);
                else
                    move_over(a,b);
            else
                if(!strcmp(str2,"onto"))
                    pile_onto(a,b);
                else
                    pile_over(a,b);
        }
        for(i=0;i<n;i++)
        {
            printf("%d:",i);
            for(j=0;j<n;j++)
                if(map[i][j]!=-1)
                    printf(" %d",map[i][j]);
            printf("\n");
        }
    }   
   
    return 0;
}

創作者介紹
創作者 RingsACM 的頭像
RingsACM

Ring's ACM

RingsACM 發表在 痞客邦 留言(0) 人氣()