zoukankan      html  css  js  c++  java
  • 天天快乐编程2020寒假提高班(临海)作业题解

    1.5211: 18岁

    你到18岁需要过几天,当然你的18岁生日还有可能不存在,比如你是今年2月29日出生的,那你每四年就只能过一个生日,18不是4的倍数,所以没生日可过。

    我们用变量sum表示我们到18岁的天数,接下来就只需要解决闰年还有平年的问题了,你是3月出生的,那今年闰年和你无关啊,你是二月前才有关联,所以二月之后生日的你需要看的是下一年是不是闰年。也就是你的1岁生日不是因为你出生的那年是闰年就是366天,而是因为1.今年是闰年,而且你是3月前出生。2.明年是闰年,而且你是3月后(包含)出生

    两个数字之间的-可以用一个char字符读入

    #include <bits/stdc++.h>
    using namespace std;
    
    //判断闰年函数
    bool isLeapYear(int y)
    {
        if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
            return true;
        return false;
    }
    
    int main()
    {
        int T;
        cin >> T;
        while (T--)
        {
            int y, m, d;
            char c;
            //读入年月日,中间用char隔开
            cin >> y >> c >> m >> c >> d;
            //总日子数sum
            int sum = 0;
            //2.29没生日输出
            if (m == 2 && d == 29)
            {
                cout << "-1" << endl;
                continue;
            }
            //3月之后(包括)看下一年
            if (m > 2)
                y++;
            //循环18年
            for (int i = y; i < y + 18; i++)
            {
                if (isLeapYear(i))
                    sum += 366;
                else
                    sum += 365;
            }
            cout << sum << endl;
        }
        return 0;
    }
    View Code

    2.1060: 鹊桥相会

    这个题目看起来很复杂,但是需要自己不去关注那些无用的条件。因为喜鹊只能往一个方向飞,还想带着牛郎往织女方向飞,天和是正方向,所以喜鹊的位置必须是负数或牛郎所在的位置0,喜鹊的速度必须是正数才飞对了方向。之后就是路程s是w*1000-t(因为t是负数,减去变正数),速度是v,时间t=s/v,取最小即可

    你可以估算一下最大时间,就是w=1000,t=1000,v=1,也就是10001000,我只要设置一个大于他的数就可以作为最大值了

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int w, n;
        while (cin >> w >> n, w || n)
        {
            //设置一个到达不了时间,也就是最大时间+1
            int minTime = 10001001;
            while (n--)
            {
                int t, v;
                cin >> t >> v;
                if (t <= 0 && v > 0)
                {
                    //时间=路程/速度
                    int time = (w * 1000 - t) / v;
                    if (time < minTime)
                    {
                        minTime = time;
                    }
                }
            }
            if (minTime == 10001001)
                cout << "Can't Solve
    ";
            else
                cout << minTime << "
    ";
        }
        return 0;
    }
    View Code

    3.5292: 游戏之购物

    我们可以先计算出商品总额,之后先使用满减优惠,再使用红包,使用需要注意自己的优惠券够不够,当然超过了不能不能支付负数

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int T;
        cin >> T;
        while (T--)
        {
            int n, p, q, sum = 0;
            cin >> n >> p >> q;
            for (int i = 0,x; i < n; i++)
            {
                cin >> x;
                sum += x;
            }
            //discount优惠,表示满减优惠金额
            int  dis = (sum / 400) * 50;
            //可满减比拥有的少
            if (p < dis)
                sum -= p;
            else
                sum -= dis;
            //使用红包优惠,金额比红包少
            if (sum < q)
                sum = 0;
            else
                sum -= q;
            cout << sum << endl;
        }
        return 0;
    }
    View Code

    4.5857: 桃子的高低音

    这个题目简单描述,就是一个高音就是他比两边的都高,那么我只要用每个数比较就好了,第一个和最后一个不会是高音

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    int a[N];
    int main()
    {
        int t;
        cin >> t;
        while (t--)
        {
            int n;
            cin >> n;
            for (int i = 0; i < n; i++)
                cin >> a[i];
            int num=0;
            //两边均比中间大,满足统计
            for (int i = 1; i < n - 1; i++)
                if (a[i] > a[i - 1] && a[i] > a[i + 1])
                    num++;
            cout << num << endl;
        }
    }
    View Code

    5.3016: 两圆位置关系

    两圆的位置关系,和两圆点距离有关,关系如下:

    学好编程之前一定要学好数学,加油~

    但是距离算出来是一个浮点数,直接比较可能会出问题,我们直接对其进行平方,这样也不需要考虑谁大谁小了,不需要取绝对值了

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int x1, y1, r1;
        while (cin >> x1 >> y1 >> r1)
        {
            int x2, y2, r2;
            cin >> x2 >> y2 >> r2;
            int D = (r1 + r2) * (r1 + r2), d = (r1 - r2) * (r1 - r2);
            double len = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
            int ans;
            //以下是if嵌套的,注意!
            if (D == len || d == len)
            {
                //两圆心距离与半径之和或之差相等
                ans = 1;
            }
            else if (len > D)
            {
                //两圆心距离大于半径之和
                ans = 2;
            }
            else if (len < d)
            {
                //两圆心距离小于于半径之差
                ans = 3;
            }
            else
            {
                ans = 4;
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code

    6.5044: 在霍格沃茨找零钱

    十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可。和时间是不是很像,1小时是60分,1分钟是60秒。这都属于进制转换题目,我们先取余,再取整抛弃这一位就可以了

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int p[3], a[3];
        char b;
        cin >> p[0] >> b >> p[1] >> b >> p[2] >> a[0] >> b >> a[1] >> b >> a[2];
        //应付的总纳特
        int sum1 = p[0] * 17 * 29 + p[1] * 29 + p[2];
        //实付的总纳特
        int sum2 = a[0] * 17 * 29 + a[1] * 29 + a[2];
        int sum = sum2 - sum1, ans[3];
        //钱没带够先输出负号
        if (sum < 0)
        {
            cout << "-";
            sum = -sum;
        }
        //获取纳特数
        ans[2] = sum % 29;
        //丢去纳特数
        sum = sum / 29;
        //获取银西可数
        ans[1] = sum % 17;
        //丢去银西可数
        sum = sum / 17;
        //sum即为加隆数
        ans[0] = sum;
        cout << ans[0] << "." << ans[1] << "." << ans[2] << endl;
    }
    View Code

    7.4020: 有道水题

    获取每一位还是需要进制转换。但是也可以直接用字符串来做这个题目,记得减去字符0

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int T;
        cin >> T;
        while (T--)
        {
            string s;
            cin >> s;
            int sum = 0;
            for (int i = 0; s[i]; i++)
                sum += s[i] - '0';
            //sum1代表从第1位到这一位总和
            //flag为0表示不存在
            int sum1 = 0, flag = 0;
            for (int i = 0; s[i]; i++)
            {
                sum1 += s[i] - '0';
                //直接除以2下取整会出问题
                if (sum1 + sum1 == sum)
                {
                    //存在结束循环
                    flag = 1;
                    break;
                }
            }
            if (flag)
                cout << "YES
    ";
            else
                cout << "NO
    ";
        }
    }
    View Code

    8.5128: 就是要62

    还是进制转换,2进制转10进制。11的二进制表示是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,也就是第i位要乘上2^(len-1)

    获取每一位的进制转换我们是倒过来,这个我们可以正过来,保证*2的次数对就可以了

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        //读入要进行转换的字符串s
        cin >> s;
        //设置变量t去保存这个答案
          int t = 0;
        for (int i = 0; s[i]; i++)
        {
            t = t * 2 + (s[i] - '0');
        }
        cout << t << "
    ";
    }
    二进制转10进制

    之后我们要把十进制转换为一位的一位,这样会帮我们倒过来

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        //读入要进行转换的字符串s
        while (cin >> s)
        {
            //设置变量t去保存这个答案
            int t = 0;
            for (int i = 0; s[i]; i++)
            {
                t = t * 2 + (s[i] - '0');
            }
            int len = 0;
            //10^9就是1后面有9个0,是十位
            int a[10];
            while (t)
            {
                //存储当前位
                a[len++] = t % 10;
                //丢弃当前位
                t /= 10;
            }
            int num = 0;
            for (int i = 1; i < len; i++)
            {
                //是26,字符串被倒过来了
                if (a[i - 1] == 6 && a[i] == 2)
                    num++;
                //是62
                if (a[i - 1] == 2 && a[i] == 6)
                    num++;
            }
            cout << num << "
    ";
        }
    }
    View Code

    9.1091: JudgeOnline

    这个题目就是判断字符,你可能会忘记了tab符' ',因为要读取空格,请整行读入

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        //有空格,直接getline
        while (getline(cin, s))
        {
            for (int i = 0; s[i]; i++)
            {
                if (s[i] == '<')
                    cout << "&lt;";
                else if (s[i] == '>')
                    cout << "&gt;";
                else if (s[i] == ' ')
                    cout << "&nbsp;";
                else if (s[i] == '	')
                    cout << "&#9;";
                else
                    cout << s[i];
            }
            cout << "
    ";
        }
    }
    View Code

    10.5858: 桃子的游戏

    题意其实也蛮简单的,就是三个人初始是x、y和z,之后每个时间+i,然后按照两个条件进行加减点数,但是是一个三重循环

    第一重循环是T组,第二重是q组,第三重是t的枚举

    记得使用long long,1e5+(1+1e4)/2*1e4超过了int

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int T;
        cin >> T;
        //有T组
        while (T--)
        {
            int x, y, z;
            //读入三个初始值
            cin >> x >> y >> z;
            int q;
            cin >> q;
            while (q--)
            {
                int n;
                //读入这次查询的时间
                cin >> n;
                //用X、Y和Z代表他们的当前值,但是这个值会超过int
                long long X = x, Y = y, Z = z;
                for (int i = 1; i <= n; i++)
                {
                    //每个人都可以得到i点
                    X += i, Y += i, Z += i;
                    if (Y >= 3)
                    {
                        //小明给桃子3点
                        Y -= 3;
                        X += 3;
                    }
                    if (Z >= 6)
                    {
                        //小强给桃子6点
                        Z -= 6;
                        X += 6;
                    }
                }
                //最后是否比两个人的大
                if (X > Y && X > Z)
                    cout << "Yes
    ";
                else
                    cout << "No
    ";
            }
        }
        return 0;
    }
    View Code

    11.5265: 围棋入门

    如果这个棋子是白棋,那么他周围这四个就有可能要被你输出。所以去找到所有的白棋,看看其是否要输出

    还有一个事情很麻烦,就是边界,我们不能越界,那我们可以将其第0行第0列空出来

    行号从小到大的顺序输出,如果行号相同,则按照列号从小到大的顺序,这个我们用一个数组去记录我们的答案

    #include <bits/stdc++.h>
    using namespace std;
    int ans[25][25];
    char s[25][25];
    //定义方向数组dir
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    int main()
    {
        //读入第一行,存储从s[1][1]开始
        while(cin>>(s[1]+1))
        {
            int n=19;
            for(int i=2;i<=n;i++)
            {
                //读入第i行,存储从s[i][1]开始
                cin>>(s[i]+1);
            }
            //清空答案
            memset(ans,0,sizeof(ans));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    //枚举每一个棋子,是W,需要找四个棋子
                    if(s[i][j]=='W')
                    {
                        for(int k=0;k<4;k++)
                        {
                            int x=i+dir[k][0];
                            int y=j+dir[k][1];
                            //是.代表可以放置
                            if(s[x][y]=='.')ans[x][y]=1;
                        }
                    }
                }
            }
            //假设白棋已经被围住
            int flag=1;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    //枚举每一个坐标看是否需要输出,这样可以保证先行再列
                    if(ans[i][j])
                    {
                        cout<<i<<" "<<j<<"
    ";
                        flag=0;
                    }
                }
            }
            if(flag)cout<<"YuYu Wins!
    ";
        }
    }
    View Code

    12.1437: Zigzag

    是不是和蛇形矩阵有点像,但是这个题目需要自己去设计循环,是一样的斜线,但是这个题还有方向,对角线可能是从左下到右上,也有可能是右上到左下

    所以我们还需要借助一个变量去控制现在是哪个方向

    flag=1代表左下到右上,也是一开始的方向,flag=-1代表从右上到左下,然后让其循环

    最后的右下角重新找规律输出

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int n, a[25][25];
        while (cin >> n ,n)
        {
            int s = 1, flag = 1;
            //对角线和为i
            for (int i = 0; i < n; i++)
            {
                //左下开始是0
                for (int j = 0; j <= i; j++)
                {
                    //左下到右上填充,否则颠倒填充
                    if (flag == 1)
                        a[i - j][j] = s++;
                    else
                        a[j][i - j] = s++;
                }
                flag = -flag;
            }
            //右下角,最后是2n-2
            for (int i = n; i < n + n-1; i++)
            {
                //左下开始是n-i
                for (int j = i-n+1; j < n; j++)
                {
                    cout<<j<<" "<<i-j<<"
    ";
                    if (flag == 1)
                        a[i - j][j] = s++;
                    else
                        a[j][i - j] = s++;
                }
                flag = -flag;
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (j != 0)
                        cout << " ";
                    printf("%-3d", a[i][j]);
                }
                cout << endl;
            }
            cout<<"
    ";
        }
        return 0;
    }
    View Code

    13.1438: 螺旋形

    这个题目就麻烦了,之前你们没有见过,但是我们可以思考一下,每次我们都是四个操作,向右,向下,向左,向上,一圈一圈往里填。

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int n, a[25][25];
        while (cin >> n, n)
        {
            //n是1没有四个方向特判掉
            if (n == 1)
                a[0][0] = 1;
            else
            {
                //i和j代表当前要填充的坐标,now是当前要填的数,N是最大可以填的数字
                int i = 0,j = 0, now = 1, N = n * n;
                //设置四个上下左右变量,代表当前所在位置
                int U = 0, D = n - 1, L = 0, R = n - 1;
                while (now <= N)
                {
                    //向右走,列++
                    while (j < R && now <= N)
                    {
                        a[i][j] = now++;
                        j++;
                    }
                    //向下走,行++
                    while (i < D && now <= N)
                    {
                        a[i][j] = now++;
                        i++;
                    }
                    //向左走,列--
                    while (j > L && now <= N)
                    {
                        a[i][j] = now++;
                        j--;
                    }
                    //向上走,行--
                    while (i > U && now <= N)
                    {
                        a[i][j] = now++;
                        i--;
                    }
                    //缩一圈,i和j各加1
                    i++,j++;
                    //缩一圈,U到了下一行,D到上一行,L到下一列,R到前一列
                    U++, D--, L++, R--;
                    //填充最后一个数
                    if (now == N)
                        a[i][j] = now++;
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (j != 0)
                        cout << " ";
                    printf("%-3d", a[i][j]);
                }
                cout << endl;
            }
            cout << "
    ";
        }
    }
    View Code

    这篇博客还有两种写法,你需要推算出下标所对应的数字或者按照循环的方式去解答

    14.3297: 名侦探柯南-破解死亡讯息 

    需要读懂这个题目,拿到字符s[i]代表的是我们这一密码段有s[i]-'A'个字符,这s[i]-'A'个字符要进一步解码,变为数字求和

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        while (cin >> s)
        {
            for (int i = 0; s[i]; i++)
            {
                //sum为当点段解码,c代表当前密码段有几个
                int sum = 0, c = s[i] - 'A' + 1;
                for (int j = i; j < i + c; j++)
                    sum = sum + s[j] - 'A' + 1;
                cout << sum;
                //下一次访问i+c,因为还要执行i++,回退一个
                i = i + c - 1;
            }
            cout << "
    ";
        }
        return 0;
    }
    View Code

    15.5168: 报时助手

    一个比较复杂的模拟题,我们需要考虑各种情况,这个题目要先思考好在再动手

    我只是提供一种代码实现,你也可以自己想一个思路去避所有可能产生的bug,从而AC题目

    #include <bits/stdc++.h>
    using namespace std;
    
    string s[25] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
    int main()
    {
        int m, n;
        cin >> m >> n;
        //m比20小,我们已经有了输出答案
        if (m <= 20)
            cout << s[m];
        else
        {
            //将其拆成20+(m-20)进行输出
            cout << s[20] << " " << s[m - 20];
        }
        //是整点直接输出
        if (n == 0)
        {
            cout << " o'clock";
        }
        else if (n <= 20)
        {
            //小于20直接输出
            cout << " " << s[n];
        }
        else if (n < 30)
        {
            //将其拆成20+(n-20)进行输出
            cout << " " << s[20] << " " << s[n - 20];
        }
        else if (n < 40)
        {
            //将其拆成30+(n-30)进行输出
            cout << " thirty";
            //n-30是0不能输出
            if (n - 30)
                cout << " " << s[n - 30];
        }
        else if (n < 50)
        {
            //将其拆成40+(n-40)进行输出
            cout << " forty";
            //n-40是0不能输出
            if (n - 40)
                cout << " " << s[n - 40];
        }
        else
        {
            //将其拆成50+(n-50)进行输出
            cout << " fifty";
            //n-50是0不能输出
            if (n - 50)
                cout << " " << s[n - 50];
        }
        cout << "
    ";
        return 0;
    }
    View Code

    16.5136: 隧道有多长

    这个题目也不难,就是你需要统计一个字符串中间有多少个连续的'#',当然也会不存在,所以最小值这个特别注意

    我们可以一重循环去统计

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        while (cin >> s)
        {
            //用mi和mx来记录答案,t来记录当前的长度
            int mi = 0, mx = 0, t = 0;
            for (int i = 0; s[i]; i++)
            {
                //是'#'需要将隧道长度+1
                if (s[i] == '#')t++;
                //其他需要统计答案的情况
                //1.不是隧道 2.最后一个字符了
                if (s[i] == '*' || s[i + 1] == 0)
                {
                    //最小值不是0取小
                    if (mi)
                    {
                        //t也不是0才能更新
                        if (t)
                            mi = min(mi, t);
                    }
                    else
                        mi = t;
                    //最大值不是0,取大
                    if (mx)
                    {
                        mx = max(mx, t);
                    }
                    else
                        mx = t;
                    t = 0;
                }
            }
            cout << mi << " " << mx << endl;
        }
        return 0;
    }
    View Code

    17.3212: Pig在哪里

    这个题目也很简单,你需要判断连续的三个字符是不是pig

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int T;
        cin >> T;
        while (T--)
        {
            int n;
            string s;
            cin>>n>>s;
            int num=0;
            //从可以访问i-2开始
            for(int i=2;i<s.length();i++)
            {
                if(s[i-2]=='p'&&s[i-1]=='i'&&s[i]=='g')
                    num++;
            }
            cout<<num<<"
    ";
        }
        return 0;
    }
    View Code

    18.3134: 渊子赛马修改版

    课堂上贪心的一个扩展,这个题目还是有一定难度的,允许平局我就得考虑这把怎么要平局

    1.最好的最差都可以,那就赢了2.渊子最好的马比对手差,直接用下等马输掉3.相等,如果最差的马太菜,输掉,否则平局

    代码会比思想更直观些

    #include<bits/stdc++.h>
    using namespace std;
    int a[10005],b[10005];
    int main()
    {
        int n;
        while(cin>>n,n)
        {
            for(int i=0; i<n; i++)cin>>a[i];
            //渊子的马从小到大排序
            sort(a,a+n);
            for(int i=0; i<n; i++)cin>>b[i];
            //对手的马从小到大排序
            sort(b,b+n);
            //aL(a数组左端点)是渊子当前最差的马的下标
            //aR(a数组右端点)是渊子当前最好的马的下标
            //bL是对手当前最差的马的下标,aR是对手当前最好的马下标
            int aL=0,bL=0,aR=n-1,bR=n-1;
            //ans代表当前的净胜场数
            int ans=0;
            for(int i=0; i<n; i++)
            {
                if(a[aL]>b[bL])
                {
                    //渊子最差的马比对手的还好,直接比掉
                    aL++,bL++,ans++;
                }
                else if(a[aR]>b[bR])
                {
                    //渊子最好的马比对手的还好,也可以直接比掉
                    aR--,bR--,ans++;
                }
                else if(a[aR]<b[bR])
                {
                    //渊子最好的马比对手差,直接用下等马输掉
                    aL++,bR--,ans--;
                }
                else if(a[aR]==b[bR])
                {
                    //最好的马相等,那么我需要考虑一下
                    //渊子最差的马比对手好的马差了,算了,用差马输出了
                    if(a[aL]<b[bR])ans--;
                    //如果相等呢,那就是渊子剩下的马全一样了,直接平局就行
                    //!!!这个平局很重要,没有净胜减少
                    aL++,bR--;
                }
            }
            //净胜场数为正,为0,为负分别对应三种情况
            if(ans>0)
                cout<<"Win
    ";
            else if(ans==0)
                cout<<"Draw
    ";
            else cout<<"Lost
    ";
        }
        return 0;
    }
    View Code

    19.5725: 营养膳食

    贪心,按照脂肪指数从高到低排序,这种种类还可以选择就选择,且只能选m个。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    struct T
    {
        int ai, bi;
    } a[N];
    int num[N];
    bool cmp(T a, T b)
    {
        return a.ai > b.ai;
    }
    int main()
    {
        int n, m, k;
        cin >> n >> m >> k;
        for (int i = 1; i <= k; i++)
            cin >> num[i];
        for (int i = 0; i < n; i++)
            cin >> a[i].ai >> a[i].bi;
        //按照ai进行排序,先吃脂肪指数高的
        sort(a, a + n, cmp);
        int sum = 0;
        //进来选食物
        for (int i = 0; i < n; i++)
        {
            //当前类别可选
            if (num[a[i].bi])
            {
                //把脂肪指数加上
                sum = sum + a[i].ai;
                //这种种类的少一份
                num[a[i].bi]--;
                m--;
                if (!m)break;
            }
        }
        cout << sum;
        return 0;
    }
    View Code

    20.3457: 最小新数

    又回到了之前的进制转换,你可以得到0~9出现的位数

    这个题目也是贪心,你需要从小开始输出,但是你不能直接先输出0,一个数不能从0开始,所以你要先输出一个。

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string s;
        while(cin>>s)
        {
            //看0~9的出现次数
            int a[10]={0};
            for(int i=0;s[i];i++)
                a[s[i]-'0']++;
            //先输出一个非0最小数字
            for(int i=1;i<10;i++)
            {
                if(a[i]>0)
                {
                    cout<<i;
                    a[i]--;
                    break;
                }
            }
            //继续从0开始,从小到大输出
            for(int i=0;i<10;i++)
            {
                while(a[i])
                    cout<<i,a[i]--;
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    21.6149: 因子个数排序

    排序我们可以直接使用sort,那记录一个因子我们还需要结构体吗?
    可以不用,因为排序的速度很快,所以你的函数调用次数也有限,所以我们可以把因子个数直接写在cmp函数里。
    怎么求因子个数,循环1~n,看看是不是因子,但是不能通过这个题目,因为数据太大了,不能在求因子浪费太多时间。其实我们找到1个因子其实就能找到2个,找到了因子i那么还有因子n/i,但是完全平方数(这个数等于两个相同的数相乘,比如4、9、16)只能计算一次,需要特殊判断。所以我们只要找到sqrt(n)就可以了。
    #include <bits/stdc++.h>
    using namespace std;
    int a[205];
    //计算因子个数函数
    int cal(int n)
    {
        //sqrt是浮点数,可能会有问题,+0.5不会出问题
        int x = sqrt(n + 0.5);
        //因为你最多算到一半,算出来因子i,那么n/i也是
        int s = 0;
        for (int i = 1; i <= x; i++)
        {
            if (n % i == 0)
            {
                //3*3=9,这种完全平方特殊处理下
                if (i * i == n)
                    s++;
                else
                    s += 2;
            }
        }
        return s;
    }
    int cmp(int s, int t)
    {
        //分别计算两数因子数
        int s1 = cal(s), s2 = cal(t);
        //相等,比较两个大小
        if (s1 == s2)
            return s > t;
        return s1 > s2;
    }
    int main()
    {
        int n;
        while (cin >> n)
        {
            for (int i = 0; i < n; i++)
                cin >> a[i];
            sort(a, a + n, cmp);
            for (int i = 0; i < n - 1; i++)
                cout << a[i] << " ";
            cout << a[n - 1] << "
    ";
        }
        return 0;
    }
    View Code

    22.3148: 按1的个数排序

    这个题依旧可以直接sort,然后我们也在cmp中统计1的个数,当然你也可以用结构体实现
    #include<bits/stdc++.h>
    using namespace std;
    string s[100];
    int cmp(string s,string t)
    {
        //分别找到两个字符串1的个数
        int s1=0,s2=0;
        for(int i=0;s[i];i++)
            if(s[i]=='1')s1++;
        for(int i=0;t[i];i++)
            if(t[i]=='1')s2++;
        //1的个数相等,按照s和t字典序排序
        if(s1==s2)return s<t;
        return s1<s2;
    }
    int main()
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>s[i];
        sort(s,s+n,cmp);
        for(int i=0;i<n;i++)
            cout<<s[i]<<endl;
        return 0;
    }
    View Code

     

  • 相关阅读:
    ios系统滚动穿透
    移动h5 开发遇到ios系统的各种问题汇总
    移动端选择时间时软键盘弹出问题
    ios系统设置-webkit-overflow-scrolling: touch导致z-index 失效 (弹窗层级设置无效)- 替代方案
    npm i 报错 npmERR! code Z_BUF_ERROR errno -5 // 后继 chromedriver.zip 相关问题报错解决
    mysql、orcale、sql server的区别
    jsp中的select选择
    sql面试
    java面试题
    struts2总结
  • 原文地址:https://www.cnblogs.com/BobHuang/p/12297272.html
Copyright © 2011-2022 走看看