1. 程式人生 > >資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第四章 遞迴演算法

資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第四章 遞迴演算法

//1206 放蘋果 遞迴
//1192 放蘋果
//http://www.cnblogs.com/dongsheng/archive/2012/08/15/2640468.html此文介紹得不錯,摘抄如下:
//8    解題分析:
//9         設f(m,n) 為m個蘋果,n個盤子的放法數目,則先對n作討論,
//10         當n>m:必定有n-m個盤子永遠空著,去掉它們對擺放蘋果方法數目不產生影響。即if(n>m) f(m,n) = f(m,m)  
//11         當n<=m:不同的放法可以分成兩類:
//12         1、有至少一個盤子空著,即相當於f(m,n) = f(m,n-1);  
//13         2、所有盤子都有蘋果,相當於可以從每個盤子中拿掉一個蘋果,不影響不同放法的數目,即f(m,n) = f(m-n,n).
//14         而總的放蘋果的放法數目等於兩者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
//15     遞迴出口條件說明:
//16         當n=1時,所有蘋果都必須放在一個盤子裡,所以返回1;
//17         當沒有蘋果可放時,定義為1种放法;
//18         遞迴的兩條路,第一條n會逐漸減少,終會到達出口n==1;
//19         第二條m會逐漸減少,因為n>m時,我們會return f(m,m) 所以終會到達出口m==0.
//該題可以放在閱讀程式寫結果
//覺得很奇怪,演算法沒問題,反覆看題,也覺得沒問題,再看未通過理由,發現格式錯誤
//原來是小錯誤啊,修改,提交AC。
#include <stdio.h>
int f(int m,int n){
    if(m==0||n==1)return 1;
    if(m<n)return f(m,m);
    return f(m,n-1)+f(m-n,n);
}
int main(){
    int m,n,i,j,k;
    scanf("%d",&k);
    for(i=1;i<=k;i++){
        scanf("%d%d",&m,&n);
        printf("%d\n",f(m,n));//此處寫成printf("%d",f(m,n));
    }
    return 0;
}


//1207 求最大公約數問題
#include <stdio.h>
int gcd(int a,int b){//a>b
    if(b==0)return a;
    return gcd(b,a%b);
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a>b)printf("%d",gcd(a,b));
    else printf("%d",gcd(b,a));
    return 0;
}

//1208 2的冪次方表示
//此文程式碼與本人極其相似,唯一不同就是此文程式碼成功了,http://www.cnblogs.com/bofengyu/p/4477355.html
//思路,先列印2(7)+2(3)+2(0)
//再對7 3 0進行處理,本人這裡沒靜下心,怎麼編也編不出,參考了上述程式碼,發現離成功只有一步
//不過,相比 洛谷  P1010 冪次方 http://blog.csdn.net/mrcrack/article/details/61625530
//已經有了長足的進步
//該題是邊編寫邊除錯的典範。2017-11-7 18:51
//抽空,還是要獨立再進行編寫一次。
#include <stdio.h>
void f(int n,int step){
    if(n==0)return;
    f(n/2,step+1);
    if(n%2==1){
        if(n/2!=0){
            printf("+");
        }
        if(step==1)printf("2");//此處新增
        else{
            printf("2(");
            if(step==0)printf("0");
            else f(step,0);
            printf(")");
        }
    }
}
int main(){
    int n;
    scanf("%d",&n);
    f(n,0);
    return 0;
}

//1209 分數求和
//該題比較簡單
//基本思路,先通分,分子求和,之後用GCD求最大公約數即可
//提交,未通過,測試點3,4,7,9答案錯誤
//讀題,發現“p,q均不超過10。” 明白了,可以等於10,而之前的處理是按1-9進行的,馬上進行修改
//提交AC。2017-11-7 20:35
#include <stdio.h>
int a[20],b[20];
long long gcd(long long a,long long b){//a>=b
    if(b==0)return a;
    return gcd(b,a%b);
}
int main(){
    int n,k=0,i;
    long long son=0,mother=1,y;
    char s[20];
    scanf("%d",&n);
    while(n--){
        scanf("%d/%d",&a[k],&b[k]);
        k++;
    }
    for(i=0;i<k;i++)mother*=b[i];
    for(i=0;i<k;i++)son+=mother*a[i]/b[i];
    y=gcd(mother,son);
    mother/=y,son/=y;
    if(mother==1)printf("%lld",son);
    else printf("%lld/%lld",son,mother);
    return 0;
}
//1210 因子分解
//此題思路 與 1200 分解因數 十分接近
//樣例通過,提交AC 2017-11-222 18:51
//exit(0);//退出遞迴 有一個問題,除了此法,還有其他方法能退出遞迴嗎?突然想到,不要回溯,即可 ,真是佩服自己,這個想法有突破
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int a[110],n,d[110];
void f(int b,int step){//犯了嚴重的錯誤,將d[110]寫成b[110],請注意,要呼叫外部的資料,名字不能與b重名
    int i,ans=1,k=0;
    for(i=1;i<=step-1;i++)ans*=a[i];
    if(ans>n)return;
    if(ans==n){
        memset(d,0,sizeof(d));
        for(i=1;i<=step-1;i++)
            d[a[i]]++;
        for(i=1;i<=n;i++){
            if(d[i]){
                k++;
                if(k==1){//第一個數字列印
                    printf("%d",i);
                    if(d[i]>1)printf("^%d",d[i]);
                }else{
                    printf("*%d",i);
                    if(d[i]>1)printf("^%d",d[i]);
                }
            }
        }
        //exit(0);//退出遞迴 有一個問題,除了此法,還有其他方法能退出遞迴嗎?突然想到,不要回溯,即可 ,真是佩服自己,這個想法有突破
    }
    for(i=a[step-1];i<=n;i++)
        if(b%i==0)b/=i,a[step]=i,f(b,step+1);//刪除 b*=i 不要回溯
}
int main(){
    scanf("%d",&n);
    a[0]=2;
    f(n,1);
    return 0;
}  


//1211 判斷元素是否存在
//樣例通過,提交,未通過
//測試點2,3,4,6,8,10答案錯誤
//http://www.cnblogs.com/huashanqingzhu/p/7745662.html程式碼啟發很大
//提供一組測試資料
//輸入:
//0 7
//輸出:
//YES
//提交,未通過,一看,測試資料未刪除,修改,提交AC 2017-11-7 21:41
#include <stdio.h>
int k;
int f(int x){
    if(x==k)return 1;
    if((x-1)%3==0&&(x-1)%2==0)return f((x-1)/3)||f((x-1)/2);//漏了此行
    if((x-1)%3==0)return f((x-1)/3);
    if((x-1)%2==0)return f((x-1)/2);
    return 0;
}
int main(){
    int x;
    scanf("%d,%d",&k,&x);
    if(f(x))printf("YES");
    else printf("NO");
    return 0;
}

2017-11-23 21:30 AC 該章節內容

相關推薦

資訊奧賽C++第二部分 基礎演算法 第一 高精度計算

第一章 高精度計算 模板在最後。 T1307 : 高精度乘法 時間限制: 1000 ms 記憶體限制: 65536 KB 【題目描述】 【輸入】 【輸出】 【輸入樣例】 【輸出樣例】 【答案&程式碼】 T1308 : 高精除 時間限制:

資訊奧賽C++ 第二部分 基礎演算法 廣度優先搜尋算

//1329 【例8.2】細胞//編寫過程中,發現輸入資料用整數無法讀取,要採用字串形式//核心思路,將非零數字字元改成0字元 //將程式碼修改,提交AC #include <stdio.h>int n,m,next[][2]={{1,0},{-1,0},{0,1},{0,-1}};char a[

資訊奧賽C++ 第二部分 基礎演算法 第一 高精度計算

//1307 【例1.3】高精度乘法 //手動模擬乘法運算 //提交,測試點5,答案錯誤,猜測,應該是0的情況,沒考慮 //提供一組測試資料 //輸入: //123 //0 //輸出: //0 //考慮了0的情況,修改,提交AC 2017-11-9 //編到這裡,感覺高精度加是高精度演算法的基礎 #inc

資訊奧賽C++ 第二部分 基礎演算法 演算法

//1206 放蘋果 遞迴 //1192 放蘋果//http://www.cnblogs.com/dongsheng/archive/2012/08/15/2640468.html此文介紹得不錯,摘抄如下://8    解題分析://9         設f(m,n) 為m個蘋果,n個盤子的放法數目,則先對n

資訊奧賽C++第二部分 基礎演算法 第二 資料排序

第二章 資料排序 T1310 : 車廂重組 時間限制: 1000 ms 記憶體限制: 65536 KB 【題目描述】   在一箇舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。一個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180180

資訊奧賽C++第一部分 C++語言 陣列

第五章 陣列 第一節 一維陣列 T1102 : 與指定數字相同的數的個數 時間限制: 1000 ms 記憶體限制: 65536 KB 【題目描述】   輸出一個整數序列中與指定數字相同的數的個數。 【輸入】   輸入包含三行:   第一行為N(N≤100)N

資訊奧賽C++第一部分 C++語言 迴圈結構的程式設計

第四章 迴圈結構的程式設計 第一節 for語句 T1059 : 求平均年齡 時間限制: 1000 ms 記憶體限制: 65536 KB 【題目描述】   班上有學生若干名,給出每名學生的年齡(整數),求班上所有學生的平均年齡,保留到小數點後兩位。 【輸入】

資訊奧賽C++ 第一部分 C++語言 迴圈結構的程式設計

//1091 求階乘的和#include <stdio.h>int f(int n){    int i,ans=1;    for(i=1;i<=n;i++)        ans*=i;    return ans;}int main(){    int n,i,sum=0;    sc

資訊奧賽C++第一部分 C++語言 程式的控制結構

第三章 程式的控制結構 第一節 if選擇結構 T1039 : 判斷數正負 【題目描述】   給定一個整數NNN,判斷其正負。如果N&gt;0N&gt;0N>0,輸出positive;如果N=0N=0N=0,輸出zero;如果N&lt

資訊奧賽C++

2018年資訊學奧賽NOIP資料下載 資訊學奧賽一本通(C++版) 第一部分 C++語言 第一章 C++語言入門 //1000 入門測試題目 #include <stdio.h> int main(){ int a,b; scanf("%d%d",&a,&b)

資訊奧賽C++ 部分 資料結構

//1336 【例3-1】找樹根和孩子 //提交,未通過,明白了,孩子必須按字典序輸出 //修改,提交,AC 2017-12-13 18:54 //該題思路可以預計,與書中提供的程式碼很不相同,書中猜測用的是左子右兄表示法,日後驗證 //該題,本人思路,鄰接表,有向圖. //很明顯,水平上了一個臺階。 #i

資訊奧賽C++ 部分 資料結構 第二 佇列

//1334 【例2-3】圍圈報數//迴圈佇列,取模,數列空出一個空間//提交,未通過,執行超時//90分程式碼 #include <stdio.h>int q[10000];int main(){    int n,m,h,t,i,mod;    scanf("%d%d",&n,&

資訊奧賽C++ 網站補充題目

//1414 【2017NOIP普及組】成績 //樣例通過,提交AC 2017-12-31 21:45 #include <stdio.h> int main(){     int a,b,c;     scanf("%d%d%d",&a,&b,&c);     prin

資訊奧賽C++ 部分 資料結構 圖論演算法

 資訊學奧賽一本通(C++版) 第三部分 資料結構   第四章 圖論演算法 http://ybt.ssoier.cn:8088/ 第一節 圖的遍歷 //1341 【例題】一筆畫問題 //在想,是輸出尤拉路,還是歐拉回路 //從哪點開始遍歷, //點的資料範圍,邊的資料範圍

資訊奧賽演算法C++基礎演算法:高精度計算 高精度加法(大位相加)

2018年資訊學奧賽NOIP資料下載 1 #include <bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 char a1[100],b1[100]; 6 int a[100],b[100],c[100];/

C++資訊奧賽題庫1032

大象喝水查 時間限制: 1000 ms         記憶體限制: 65536 KB 提交數: 1472     通過數: 969 【題目描述】 一隻大象口渴了,要喝20升水才能解渴,但現在只有一個深h釐米,底面半徑為r釐米的小圓桶(h和r都是整數)。問大象至少要喝

資訊奧賽 小球drop

2018年資訊學奧賽NOIP資料下載 This drop is gonna last forever! 許多的小球一個一個的從一棵滿二叉樹上掉下來組成FBT(Full Binary Tree,滿二叉樹),每一時間,一個正在下降的球第一個訪問的是非葉子節點。然後繼續下降時,或者走右子樹,或

資訊奧賽 1299糖果#線性動態規劃#

題意:給出n個數,找出若干個數,使它們的和為k的倍數,並輸出最大的數。狀態轉移方程:f[i][j]表示前i個數%k=j的總數。f[i][j]=max(f[i-1][j],f[i-1][tmp]+a[i]

C++資訊奧賽題庫1036A*B問題

A*B問題 時間限制: 1000 ms         記憶體限制: 65536 KB 提交數: 3404     通過數: 956  【題目描述】 輸入兩個正整數A和B,求A*B的值。注意乘積的範圍和資料型別的選擇。 【輸入】 一行,包含兩個正整數A和B,中間用單個空格隔

C++資訊奧賽題庫1034計算三角形面積

計算三角形面積 時間限制: 1000 ms         記憶體限制: 65536 KB 提交數: 1813     通過數: 622  【題目描述】 平面上有一個三角形,它的三個頂點座標分別為(x1, y1), (x2, y2), (x3, y3),那麼請問這個三角形的