用对拍程序来debug错误程序的错误数据
對拍就是通過把自己寫的程序的結果和一個完全正確的程序結果進行比較 從而得出自己寫的錯誤程序的漏洞
比如這道題
24點游戲 EOlymp - 44
The number of ones
In arithmetic expression you are allowed to use the number?1, operations of addition, multiplication and parenthesis. What is the minimum number of ones you need to obtain the positive integer?n?
Input
One number?n?(1?≤?n?≤?5000).
Output
The required number of ones.
?
題意:將輸入的數字 只能通過用1和加乘運算表示出來 問這個數字最少用多少1?
一開始自己想到遍歷因數 盡可能用小的因數相乘 不斷累積小的因數 從而獲得這個數 如果是質數 就-1先算偶數的結果然后?
最后再加1 那么這種做法WA?
復雜度分析:每一個結果要計算O(sqrt(n))次
最大sqrt(5000)約等于71
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 5010; bool bok[maxn]; int cnt; void div(int n){if(n<=5){cnt+=n;return;}if(!bok[n]){cnt++;div(n-1);}else {for(int i=2;i*i<=n;i++){if(n%i==0){cnt+=i;div(n/i);break;}}} } int main() {freopen("in.txt","r",stdin);freopen("pro.txt","w",stdout);for(int i=2;i<=5000;i++){if(!bok[i])for(int j=i+i;j<=5000;j+=i){bok[j] = 1;}}int n;while(~scanf("%d",&n)){div(n);printf("%d\n",cnt);cnt=0;}return 0; }此時可以考慮用對拍檢測法檢測程序
?
AC程序:
而正確做法動態規劃 應該這么做?
對每一個數遍歷所有可能乘到這個數的可能 然后從中選擇最小的記錄下來?
符合動態規劃的最優子結構 和重疊子問題 性質 因為大數是通過小數的結果反饋得來
復雜度分析:對于任何一個結果O(n*sqrt(n))
另外數據生成程序:
#include<bits/stdc++.h> using namespace std; int main() {freopen("in.txt","w",stdout);for(int i=1;i<=5000;i++){printf("%d\n",i);}return 0; }把所有數據范圍的數據都遍歷了
或者我們生成隨機數
#include<cstdio> #include<cstring> #include<iostream> #include<ctime> #include<cstdlib> using namespace std; typedef long long ll; int main() {freopen("in.txt","w",stdousrand(time(0));//初始化隨機數生成器for(int i=1;i<=100;i++){printf("%d\n",rand()%5000+1);}//注意srand和rand如果放到一起寫 一般同一秒內生成的隨機數是相同的//因為time(0)是根據1970年1月1日00點00分00秒開始到現在的秒數return 0; }最后測試程序
#include<bits/stdc++.h> #include<windows.h> using namespace std; stringstream ss; int main(int argc,char *argv[]) {int t= 100;system("data.exe");//運行數據生成程序int s1 = clock();system("right.exe");//執行正確程序int e1 = clock();cout<<s1<<endl;system("pro.exe");//執行錯誤程序int e2 = clock();cout<<e2<<endl;Sleep(1000);//程序暫停1scout<<e1-s1<<" "<<e2-e1<<endl;//輸出兩個程序的耗費時間(ms)if(system("fc pro.txt right.txt")){//比較兩個文件是否存在不同printf("WA");}return 0; }那么運行最后的錯誤程序 就能看到是否有不一樣輸出的地方了
最后發現46這里有問題:
自己的程序
46 = 2*23
23 = 1+22
22 = 2*11
11 = 1+10
10 = 2*5
sum up:2+1+2+1+2+5 = 13
正確程序:比如 46 就是遍歷所有的可能 dp[45]+1?
或者通過 45 = 5*9
9 = 3*3?
sum up : 1+5 + 3+3 = 12
這種結果并不是通過因數拆分得到的 而是通過遍歷所有可能選出最小的可能 而雙數在錯誤程序中 必定是一個通過2去化簡的數
所以這種情況直接略過了從45過渡過來的可能 略過了最小的可能 所以當選擇極限方案時 還是不僅要考慮貪心 也要考慮DP
貪心是我們已知的最優解的走法 而動態規劃是我們要從所有子問題分支中依據數值選擇出最優的分支?
對于問題的判斷不清 很容易選擇貪心算法 錯誤的選擇了最優分支 而不忽略了真正的最優可能分支
那么對拍檢測4步:
1 自己的待查程序
2 一個正確/暴力程序
3 一個輸出生成程序
4 測試程序
四個程序最好放到同一目錄結構下
運行測試程序 找出錯誤實例
?
總結
以上是生活随笔為你收集整理的用对拍程序来debug错误程序的错误数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工业项目实施-URS(用户需求说明)
- 下一篇: C# Winform开发人脸识别小程序