POJ1416-Shredding Company

題目鏈接:點擊打開鏈接

簡單的搜索技巧與剪枝,不多說了心累,保存路徑。。。

//164K	0MS
//C++	1331B
#include <cstring>
#include <cstdio>
int p[6]={100000,10000,1000,100,10,1};  //類似於迷宮方向數組的感覺
int n,sum,dis[6],z;                          //z爲遞歸的編號,防止重複路徑覆蓋,每一次遞歸編號都是不同的
int mx,f,x;
struct node
{
    int pi;                                          //前一次遞歸的編號
    int num;                                     //當前的剪出的數字
}q[33];
void dfs(int k,int m,int l,int w)
{
    int i;
    for(i=l;i<5;i++)                            //由當前位數開始查找到最後,因爲有前導零的情況,所以要記錄位數
    {
        int h=m;                                 //當前要剪切的數字
        if(k-h/p[i]>=0)
        {
            q[++z].pi=w;                      //記錄當前遞歸的編號
            q[z].num=h/p[i];               //記錄剪下來的數字
            dfs(k-h/p[i],h%p[i],i+1,z); //遞歸下一次的目標數,剩餘數
        }
    }
    if(m<=k)                                  //若當前數已經不大於當前目標數
    {
        if(mx<n-k+m)                     //更新mx
        {
            q[++z].pi=w;                   //記錄路徑
            q[z].num=m;
            x=z;f=0;                          //返回路徑起點編號
            mx=n-k+m;
        }
        else if(mx==n-k+m)
        {
            f=1;                                 //若最大值重複則標記,出現新的最大值時刪除標記
        }
    }
}
int main()
{
    int m,i,j;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        memset(dis,0,sizeof(dis));
        f=0;                                   //重複標記
        x=-1;                                 //路徑終點編號
        z=0;                                  //遞歸編號
        mx=-1;                             //最接近切割數
        for(i=0;i<6;i++)                //找出這個數的位數;
            if(m/p[i]>0)
                break;
        dfs(n,m,i,z);                     //當前目標數,當前數,當前數的位數對應的p數組下標,當前的遞歸次數
        if(mx==-1)
            printf("error\n");
        else if(f)
            printf("rejected\n");
        else
        {
            printf("%d ",mx);
            for(i=x,j=0;i!=0;i=q[i].pi)   //順着前一個的下標從後往前找路徑出來
            {
                dis[j++]=q[i].num;
            }
            for(i=j-1;i>=0;i--)
            {
                printf("%d",dis[i]);
                if(i)
                    printf(" ");
            }
            printf("\n");
        }

    }
    return 0;
}

經歷過網絡賽心更累了,補了一下注釋。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章