第七週程序設計課解題報告

第七週程序設計課解題報告
1.different triangs
題目大意:給出n條邊,任取其中三條,問有多少種情況取出的三條邊能組成三角形。
解:先使用數組把邊長存起來,然後用三重循環去枚舉取邊方案,再用if語句判斷取出的三條邊是否能組成三角形(我使用了函數實現這個功能) 
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


using namespace std;


bool check(int a, int b, int c){
    if ((a+b>c)&&(a+c>b)&&(b+c>a)) return true;
    return false;
}


int main(){
    int n, cas, a[1111];
    cin>>cas;
    while (cas--){
        cin>>n;
        for (int i=1; i<=n; i++) cin >> a[i];
        int ans=0;
        for (int i=1; i<=n-2; i++)
            for (int j=i+1; j<=n-1; j++)
                for (int k=j+1; k<=n; k++)
                    if (check(a[i], a[j], a[k])) ans++;


        cout << ans << endl;
    }
    return 0;
}                                 








2.矩形邊框
題目大意:給出矩形的寬度和高度,輸出由*號圍成的矩形邊框.
解:很容易發現,其實除了行數爲1,h,列數爲1,w的方格應該是*號外,其他都是空格,所以用if處理輸出即可。
代碼:
// Problem#: 12074
// Submission#: 3157183
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


using namespace std;


int main(){
    int n, cas, m;
    cin>>cas;
    while (cas--){
        cin>>m>>n;
        for (int i=1; i<=n; i++){
            for (int j=1; j<=m; j++){
                if (i==1 || i==n || j==1 || j==m) cout <<'*';
                else cout <<' ';
            }
            cout << endl;
        }
        cout << endl;
    }
    return 0;
}                                 




3.分解質因數
題目大意:把每個輸入的數進行質因數拆分
解:暴力拆分也不會超時,不過其實枚舉質因數的時候枚舉到根號n就可以退出了(但是這樣做記得要枚舉自己因爲自己可能是一個質數)
代碼:(這題因爲讀錯題少行末沒有輸出空格PE了一次囧)
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


using namespace std;


int main(){
    int n;
    cin>>n;
    while (n--){
        int now;
        cin>>now; int sum=0, i=2;
        while (now>1){
            while (now%i==0){
                sum++;




                cout << i;
                cout <<' ';
                now/=i;
            }
            i++;
        }
        cout << endl;
    }
    return 0;
}                                 








4.ELLIPSE
題目大意:給出一個橢圓,問有多少個整點(比如x,y是整點的充要條件是x,y都是整數)嚴格在橢圓內部(橢圓上的點不算)
 解:相信判斷點是否在橢圓內的公式大家都會吧,所以暴力枚舉整數點就可以了,但是如果枚舉題目範圍內所有的點感覺太暴力不知道會不會跪(這是我當時的想法,現在算一算貌似不會跪>W<),我就加了一個小優化。給出焦點和長半軸長d後,可知整點一定不會小於左焦點橫座標減d(最壞情況,哪怕焦點重合,若整點座標小於左焦點橫座標減d,整點到兩焦點距離必然大於d),同理可以算出其他邊界。我繼續使用函數求距離因爲看起來會舒服一些。沒學過的同學可以試着模仿一下,相信你會喜歡這種風格的。
哦對了,我求最大最小值沒有用algorithm庫裏的max和min函數,而是我自己用define定義了這樣的寫法,有興趣學習的同學可以搜索一下define的用途以及三元運算符“ a?b:c”
擦再看一眼貌似struct大家不知道用過沒= =,不會的就問我,不要打我(抱頭) 
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)


using namespace std;


struct point{double x, y;};


double dist(point a, point b){
    return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y));
}


int main(){
    int n, cas, m;
    cin>>cas;
    while (cas--){
        point f1, f2;
        int d;
        cin>>f1.x>>f1.y>>f2.x>>f2.y>>d;
        int x1, x2, y1, y2;
        x1=MIN(f1.x, f2.x); x2=MAX(f1.x, f2.x);
        y1=MIN(f1.y, f2.y); y2=MAX(f1.y, f2.y);
        x1-=d; x2+=d;
        y1-=d; y2+=d;
        int ans=0;
        for (int x=x1; x<=x2; x++)
            for (int y=y1; y<=y2; y++){
                point tmp; tmp.x=x; tmp.y=y;
                if ((dist(f1, tmp)+dist(f2, tmp))<d) ans++;
        }
        cout << ans << endl;
    }
    return 0;
}                                  




5.Prime Palindromes
題目大意:求區間[a,b]內的迴文數素數
爲什麼要出這道題!!!!!
解:吭,跑題了。這道題感覺大家第一時間會傾向於暴力枚舉,但參見我上一篇文章,算複雜度的事情,因爲這裏b可以去到1億的,出數據的人和(喪)藹(心)可(病)親(狂)一點出幾個[5,100000000]的數據程序就tle了,所以我們不能這樣暴力做。
那麼如何優化呢?其實我們可以利用迴文數的性質很好地吧複雜度優化下來。因爲爲啥不用枚舉全部的數呢?因爲我們需要的僅僅是迴文數,而回文數知道了左半邊即可知道右半邊了。對了,我們枚舉左半邊的數就好了,哪怕是九位數,我們也只需要枚舉1~99999即可,如此我們便將複雜度從O(n)變成了O(根號n)。把迴文數求出來了便求一下是否素數就好(相信大家都會,而且我依舊是用函數實現)
PS:
當然此題存在很多細節討論,比如我枚舉生產後發現答案不是單調遞增的,所以我先把答案保存然後排序輸出。因爲考慮到大家沒有學到數組,我就沒有用拆位放入數組翻轉的方法實現還原迴文數,而是直接用數學方法(最後還是用到了數組TAT,但是你們相信我這題理論上我的方法還是不要用到數組的,跟別的組長比起來用什麼dfs還有打表這種高科技我自認爲我還是很有節操的(⊙o⊙)。想學習高科技的同學可以搜索 遞歸,打表的話私聊問吧,因爲我覺得只算技巧而不是什麼數據結構啊算法這方面的東西)  而翻轉回文數的時候要用到10的n次方冪,因此我沒有每一次都pow一下而是先預處理把要用到的次方冪保存。
PS2:我的註釋語句是我調試用的,想了一下沒有刪掉,在最後附一個刪註釋版。不會調試的可以參考下,另外sort的函數可以接觸一下,理解原理不太容易但是會用還是挺簡單的)


代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)


using namespace std;


struct point{double x, y;};


bool check(int x){
    for (int i=2; i<=trunc(sqrt(x)); i++)
    if (x%i==0) return false;
    return true;
}
int aa[1000000];
long long poww[13];


int main(){
    poww[0]=1;
    for (int i=1; i<=12; i++) poww[i]=poww[i-1]*10;
    long long a, b, now, tot;
    while (cin>>a>>b && a+b>0){
        tot=0;
        for (int lab=1; lab<=9; lab++){
            if (poww[lab-1]>b) break;
           // cout <<'!' << lab << endl;
            int lim=poww[(lab+1)/2]-1;
           // cout << lim << endl;
            for (int i=1; i<=lim; i++)if (i%2==1){
                now=i;
               // cout << i << endl;
                for (int j=1; j<=lab; j++){
                    if (lab-j+1 == j) break;
                    long long tt=(i/poww[j-1]);
                  //  cout << tt << endl;
                    now+=(poww[lab-j])*(tt%10);
                }
               // cout << i <<' '<< now << endl;
                if ((now>=a)&&(now<=b)&&(check(now))) {
                    aa[++tot]=now;
                }


            }


        }
        sort(aa+1, aa+1+tot);
        for (int i=1; i<=tot; i++)
            if (aa[i]>1) printf("%d\n", aa[i]);
    }
    return 0;
}                  




無註釋版:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>


#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)


using namespace std;


struct point{double x, y;};


bool check(int x){
    for (int i=2; i<=trunc(sqrt(x)); i++)
    if (x%i==0) return false;
    return true;
}
int aa[1000000];
long long poww[13];


int main(){
    poww[0]=1;
    for (int i=1; i<=12; i++) poww[i]=poww[i-1]*10;
    long long a, b, now, tot;
    while (cin>>a>>b && a+b>0){
        tot=0;
        for (int lab=1; lab<=9; lab++){
            if (poww[lab-1]>b) break;
            int lim=poww[(lab+1)/2]-1;
            for (int i=1; i<=lim; i++)if (i%2==1){
                now=i;
                for (int j=1; j<=lab; j++){
                    if (lab-j+1 == j) break;
                    long long tt=(i/poww[j-1]);
                    now+=(poww[lab-j])*(tt%10);
                }
                if ((now>=a)&&(now<=b)&&(check(now))) {
                    aa[++tot]=now;
                }


            }


        }
        sort(aa+1, aa+1+tot);
        for (int i=1; i<=tot; i++)
            if (aa[i]>1) printf("%d\n", aa[i]);
    }
    return 0;
}                                              
 

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