天天看點

HAUT OJ 1231: ykc買零食 問題描述: 原因分析: 解決方案:

問題描述:

ykc的班級準備舉行班級聚會,而身為生活委員的ykc要為此準備好零食,這天,ykc來到了學校的新起點超市,在轉了3個小時候,ykc決定買以下所有的n種零食,其中每種零食的價格可能不一樣,而剛好超市有活動,每買m種零食,就可以任選一種不超過k元的零食并免費贈送,而ykc想盡可能的省錢,求ykc的最小花費

輸入:

輸入包含多組資料,以EOF結束,

每組首先輸入三個正整數,n,m,k,其中(n,m,k<100)

後輸入n個數表示每種零食的價格ai(ai<1000)

輸出:

輸出一個正整數,表示最小花費

樣例輸入:

4 3 2
1 2 3 4
7 3 8
1 2 3 4 5 6 7      

樣例輸出:

8
21      

原因分析:

1. 計算免單個數時 應該n/m+1   而不是 n/m   舉個例子:免單條件是買夠3件   你若買3件,則沒有可以免的,隻有買4件才能免一件  

2.循環變量第一次忘了初始化,後來才發現;

3.減去免單的金額時,忘了标記被免單過的商品,導緻第二次重複免單,出現錯誤

解決方案:

#include<stdio.h>
#include<math.h>
int cmp(const void*a,const void*b)
{
    return (*(int*)b - *(int*)a);
}
int main()
{
    int n,m,k,s=0,i,p,j,f;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
 {
        int a[102]={0};   //多執行個體一定要注意循環變量的初始
        s=0;
        f=-1;

        for(i=0;i<n;i++)
       {
          scanf("%d",&a[i]);   
          s+=a[i];
       }
        qsort(a,n,sizeof(int),cmp);

       
        p=n/(m+1)==0?0:n/(m+1);   //不能寫成 n/m  要把免單的一個也算進m

        if(p<=0)
        printf("%d\n",s);
        else
    {

            for(i=0;i<n;i++)
             if(a[i]<=k)
            {
                f=i;     //找到小于免單金額的那個位置
                break;

            }


              if(f!=-1)
            {

               for(j=1;j<=p;j++)  // j記錄免單次數
                for(i=f;i<n;i++)
                 {
                     if(a[i]!=-1)
                    {
                       s-=a[i];
                       a[i]=-1; //第二個for每次都要從f重新開始,是以要避免重複減去免單的商品
                       break;   //減一次就要退出循環
                    }
                 }
            }

            printf("%d\n",s);

    }


 }

	return 0;
}
           

繼續閱讀