您的位置:首页 > 编程语言 > C语言/C++

第七周程序设计课解题报告

2015-04-12 22:51 190 查看
第七周程序设计课解题报告

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;

}                                              

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息