JSU省賽隊員選拔賽個人賽1(Coin Change、Fibbonacci Number、Max Num、單詞數、無限的路、疊筐)

JSU省賽隊員選拔賽個人賽1

一、題目概述:

    A、Coin Change(暴力求解、動態規劃)
    B、Fibbonacci Number(遞推求解)

    C、Max Num(排序、比較)

    D、單詞數(字符串比較、庫函數運用)

    E、無限的路(平面幾何)

    F、疊筐(規律輸出)

二、解題報告:


A、Coin Change

      給一個錢的總金額,求出用100個以內的50分、25分、10分、5分、1分硬幣拼成該金額的不同拼法。

      直接暴力,打表什麼的都是浮雲。開始總覺得用暴力求解顯得自己沒風度,不夠高端霸氣上檔次。當面臨各種WA時,什麼都是浮雲,唯有AC纔是王道。

       用i,j,k,x,y分別表示50分、25分、10分、5分、1分硬幣的數量,用四重循環直接暴力(不用五層。剩下的變量直接可以求得)。當y=n-x*5-k*10-j*25-i*50;並且y不小於0,硬幣總數不大於100的時候,表示這種拼法是可以的,計數變量sum自加一,最後直接輸出計數變量即可。

#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main() {     int n;     int i,j,k,x,y;     while(cin>>n)     {         __int64 sum=0;         for(i=0; i<=n/50; i++)   //50分的硬幣i個             for(j=0; j<=n/25; j++)   //25分的硬幣j個                 for(k=0; k<=n/10; k++)   //10分的硬幣k個                     for(x=0; x<=n/5; x++)   //5分的硬幣x個                     {                         y=n-x*5-k*10-j*25-i*50;  //一分的硬幣y個                         if(y>=0&&i+j+k+x+y<=100)sum++; //滿足要求,這種拼法是可以的                     }         cout<<sum<<endl;     }     return 0; } 

B、
Fibbonacci Number

     沒什麼好講的,直接用公式來算就好了。

     不過要注意兩點:

         (1)先打表,後面要用到的話,直接輸出即可。避免超時。

         (2)要用64爲位int,題目最大輸出第50個斐波那契數,該數超出32位int的存儲範圍。否則,數據溢出造成WA。

#include<iostream> using namespace std; int main() {     __int64 f[55];     int i,n;     f[0]=0;     f[1]=1;     for(i=2;i<55;i++)f[i]=f[i-1]+f[i-2];  //直接打表     while(cin>>n&&n!=-1)cout<<f[n]<<endl;  //直接按表輸出     return 0; }

C、Max Num

      簡單題,直接比較就好了。

      t組數據,每組數據n個,然是n個數據,求n個數據中的最大值。

       對於每一組數據,用一個初始值爲0(輸入的值都不小於0)的max比較處理。逐個輸入n個數,每個數和max比較,要是比max大,就替換max的值。後面直接輸出max的值就好了。注意用double處理數據。

#include<iostream> #include<cstdio> using namespace std; int main() {     int t,n;     double x,max;     cin>>t;     while(t--)     {         max=0;         cin>>n;         while(n--)         {             cin>>x;             if(x>max)max=x;  //直接比較替換         }         printf("%.2lf\n",max);  //直接輸出     }     return 0; } 

D、
單詞數

      稍難的題目,數單詞不難,要是常規句式(沒有空格),直接數空格就好,單詞數=空格數+1;

     問題是,這裏要的是不同的單詞的種類(句子中還可能有多個空格隔開兩個單詞,句子的前後端也可能有空格,一個回車結束一個句子)。一般的藥已經治不了他了,要想做,不放棄治療,只能用“抗生素”了。用到sscanf,從字符數組中讀取字符串,用到set容器判斷該單詞前面是否出現過。

(1)用gets輸入數據,一個gets結束就代表一個案例輸入完成(最好把用來存儲的數組開大點)。

(2)用sscanf(需要起始位置)從前到後從數組中讀出字符串(遇到空格讀取就結束),人工跳過空格。

(3)用set判斷先下讀取的單詞是否在前面出現過,要是沒有出現過,直接壓入容器,計數變量(記得初始化啊)加1。否則直接跳過。

(4)最後輸出計數變量的值即可。

#include<stdio.h> #include<string.h> #include<iostream> #include<cstring> #include<string> #include<set> using namespace std; char f[100000000]; int main() {     //freopen("in.txt","r",stdin);     __int64 n;     int i,j;     char a[1000];     while(gets(f)&&f[0]!='#')  //輸入案例數據,遇到“#”時,程序結束     {         n=0;  //計數變量初始化         set<string> s;  //定義容器s         int len=strlen(f);   //求出輸入數據的長度         for(i=0; i<len; i++)  //“逐個”檢索         {             if(f[i]==' ')continue;  //跳過空格             sscanf(f+i,"%s",a);  //讀取字符串             if(!s.count(a))  //判斷字符串是否在前面出現過(沒有出現過)             {                  n++;     //計數變量加1                 s.insert(a);   //壓入容器             }             i=i+strlen(a)-1;  //跳過已處理的字符串         }         cout<<n<<endl;   //輸出計數變量即可     }     return 0; } 

E、無限的路


集合題,鬱悶了很久。所有的點都在直線x+y=b上。。。

先處理最特殊的(0,0)點

後面求的時候分成4段

(1)前殘餘段

(2)中間直線x+y=b的線段總長度

(3)中間連接(2)中直線的線段的總長度

(4)後殘餘短

#include<stdio.h> #include<math.h> #include<algorithm> using namespace std; double f(int x,int y) {     return sqrt(x*x+y*y); } int main() {     int t;     int x,y;     int x1,y1,x2,y2;     double l;     int i,j;     scanf("%d",&t);     while(t--)     {         l=0;         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);         x=x1+y1;         y=x2+y2;         if(y<x)         {             swap(x1,x2);             swap(y1,y2);         }         if(x1==0&&y1==0)         {             l+=1;             x1=0;             y1=1;         }         if(x1+y1==x2+y2)             l+=f(x1-x2,y1-y2);         else         {             x=x1+y1;             y=x2+y2;             for(i=x+1; i<y; i++)                 l+=f(i,i);             for(i=x; i<y; i++)                 l+=f(i,i+1);             l+=f(y1,y1);             l+=f(x2,x2);         }         printf("%.3lf\n",l);     }     return 0; } 

F、疊筐

就是圈一圈的輸出的意思,用二維數組存儲圖案,一圈一圈的賦值。從裏到外,一圈賦完後改變填充值。

注意n=1時的特殊處理

注意輸出格式:

(1)案例間要換行

(2)“剪角”

#include<stdio.h> int main() {     //freopen("in.txt","r",stdin);     int n,i,j;     char a[2],b[2],c;     char pi[85][85];     int f=0;     while(scanf("%d%s%s",&n,a,b)!=EOF)     {         if(f)printf("\n");   //案例間的換行         if(n==1)  //要是隻有1個             printf("%c\n",a[0]);         else         {             c=a[0];             for(i=n/2; i>=0; i--)  //從裏到外(填充)             {                 for(j=i; j<=n-i-1; j++)                 {                     pi[i][j]=c;  //上面一行                     pi[n-i-1][j]=c;   //下面一行                     pi[j][i]=c;   //左邊一列                     pi[j][n-i-1]=c;   //右邊一列                 }                 if(c==a[0])c=b[0];   //更換“填充物”                 else c=a[0];             }             //pi[n/2][n/2]=a[0];             for(i=0; i<n; i++)             {                 for(j=0; j<n; j++)                 {                     if((i==0&&j==0)||(i==0&&j==n-1)||(i==n-1&&j==0)||(i==n-1&&j==n-1))  //“剪角”                         printf(" ");                     else                         printf("%c",pi[i][j]);                 }                 printf("\n");             }         }         f=1;     }     return 0; } 










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