• P1010 幂次方 P1022 计算器的改良


    P1010 幂次方

    一、题目

    https://www.luogu.org/problemnew/show/P1010

    二、代码

    #include<bits/stdc++.h>
    using namespace std;
    
    // 根据2的几次幂进行分解
    string decompose(int num)
    {
        if(num==0)
        {
            return "0";
        }
    
        string s = "";
        int exp = 0;  // 指数,比如2=2^1,则指数为1
        do
        {
            if(num & 1) // 判断奇数
            {
                // num=2时,exp==1才为真
                string tmp1 = exp==1 ? "2" : "2("+decompose(exp)+")";
                string tmp2 = s=="" ? "" : "+";
    
                // 拼接字符串,依题意,要把低次方接在后面
                s = tmp1 + tmp2 + s;
            }
    
            exp++;
        } while(num >>= 1);//每次向右移一位,即除以2
    
        return s;
    }
    
    int main()
    {
        int x;
        cin>>x;
        cout<<decompose(x)<<endl;
        return 0;
    }
    View Code

    P1022 计算器的改良

    一、题目

    https://www.luogu.org/problemnew/show/P1022

    二、代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int coe = 0;         // coe * x = value, coe即为x的系数
        int value = 0;
        int pos = -1;       // 数值位于等号左边的数为负(移到右边即为正),位于等号右边的数为正
        char c = getchar();
        int num = 0;        // 当前读入的数值
        int sign = 1;       // 当前数值符号,
        char x;             // 未知数,26个小写字母之一
    
        while(true)
        {
            if (c>='a' && c<='z')
            {
                x = c;
                if (num == 0)
                {
                    // 系数为1
                    coe += -pos * sign;
    
                }
                else
                {
                    coe += -pos * sign * num;   //系数左边为正,右边为负,所以pos要取负
                }
    
                num = 0;
                sign = 1;
            }
            else if (c == '-')
            {
                value += pos * sign * num;
                num = 0;
                sign = -1;
            }
            else if (c == '+')
            {
                value += pos * sign * num;
                num = 0;
                sign = 1;
            }
            else if (c >= '0' && c <= '9')
            {
                num = num * 10 + c - '0';
            }
            else if (c == '=')
            {
                value += pos * sign * num;
                num = 0;
                sign = 1;
                pos = -pos;     //等号右边pos为正
            }
            else   // 换行的时候,要把最后的数(如果有)累加到valu
            {
                value += pos * sign * num;
                break;
            }
    
            c = getchar();
        }
    
        double ans = double(value) / coe;//计算ans
    
        printf("%c=%.3f", x, ans == 0 ? abs(ans) : ans);//这涉及一个很坑的地方:C++里0除以一个负数值为-0,专门避免这种情况
    
        return 0;
    }
    View Code

    UVA524 素数环

    一、题目

    https://www.luogu.org/problemnew/show/UVA524

    二、分析

    例1:以n = 4为例。n = 4的排列有

    1,2,3,4    相邻两个数相加都是素数,符合题意
    1,2,4,3    2和4相加不是素数,不符合题意
    1,3,2,4    2和4相加不是素数,不符合题意
    1,3,4,2    4和2相加不是素数,不符合题意
    1,4,2,3    4和2相加不是素数,不符合题意
    1,4,3,2    相邻两个数相加都是素数,符合题意。
    

    所以正确的答案为

    1,2,3,4
    1,4,3,2
    

    例2:以n = 5为例。n = 5的排列有

    1,2,3,4,5   4和5相加不是素数,不符合题意
    1,2,3,5,?    3和5相加不是素数,不符合题意
    1,2,4,?    2和4相加不是素数,不符合题意
    1,2,5,3,?    5和3相加不是素数,不符合题意
    1,2,5,4,?    5和4相加不是素数,不符合题意
    1,3,?          1和3相加不是素数,不符合题意
    1,4,2,?       4和2相加不是素数,不符合题意
    1,4,3,2,5    5和1相加不是素数,不符合题意
    1,4,3,5,?    3和5相加不是素数,不符合题意
    1,4,5,?       4和5相加不是素数,不符合题意
    1,5,?          1和5相加不是素数,不符合题意
    

    所以n=5时,没有答案。

    三、代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    int a[100];
    int prime[100];
    bool visited[100]; //visited[num]用来标记num是否被使用了
    
    // pos为数组下标
    void dfs(int pos)
    {
        // num为数组中的数
        for(int num=2; num<=n; num++)
        {
            // 如果这个数已经使用,则不能再用
            if(visited[num])
            {
                continue;
            }
    
            if(prime[a[pos-1] + num])   //当前数num与上一个数的和为素数
            {
                visited[num] = true;    // 标记
                a[pos] = num;           // 存储,后面需要打印出来
                if(pos == n)            // 放完了n个数
                {
                    if(prime[a[pos] + 1]) //这是一个环,所以要计算最后一个数与第一个数1的和
                    {
                        for(int j = 1; j < n; j++)
                        {
                            printf("%d ",a[j]);
                        }
                        printf("%d
    ", a[n]);  //这里很恶心,行末不能有空格
                    }
                }
                else
                {
                    dfs(pos + 1);
                }
    
                visited[num] = false;  //回溯
            }
        }
    }
    
    int main()
    {
        // 素数打表
        prime[2]=prime[3]=prime[5]=prime[7]=prime[11]=prime[13]=prime[17]=prime[19]=prime[23]=prime[29]=prime[31]=true;     //先处理一下素数
    
        int cnt = 0;    // 输出的第几组数据
        while(scanf("%d",&n) == 1)
        {
            cnt++;
            printf("Case %d:
    ",cnt);
            a[1] = 1;   //第一个数是1
            visited[1] = true; // 这一句可写可不写,因为1就是第一个数
            dfs(2);     //从第二个数开始搜
    
            cout << endl;
        }
        
        return 0;
    }
    View Code

    P4326 求圆的面积

    一、题目

    https://www.luogu.org/problemnew/show/P4326

    二、分析

    COCI是Crotian Open Competition in Informatics, 即克罗地亚信息学公开赛。
    本题的坑点在于有些人不知道所谓的出租车几何下的“圆”其实是一个正方形:

     
     

    上面这个“圆”中,中心点到边上的任意一点的距离都为|x1 - x2| + |y1 - y2| = 4。

    这个“圆”是由上下两个三角形组成的,每个三角形的面积为2r * r / = r * r,所以“圆”的面积为2 * r * r。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    const double pi = 3.141592653589793;
    
    int main()
    {
        double r;
        cin >> r;
        printf("%.6f
    ", pi * r * r);
        printf("%.6f
    ", 2 * r * r);
    
        return 0;
    }
    View Code

    P1009 阶乘之和

    #include<iostream>
    using namespace std;
    
    int a[2000];
    int c[2000];
    const int maxDigit=1000; //最大位数,调试时可设n=4,maxDigit=3
    
    // 阶乘相加
    void add(int *a,int *c)
    {
        int carry = 0;
        // 比如1!+2!+3!+4!
        // i=1时,c[1]=1!=1
        // i=2时,c[1]=1+2!=3
        // i=3时,c[1]=3+3!=9
        // i=4时,c[1]=9+4=13,carry=1,c[1]=3,c[2]=c[2]+a[2]+carry=0+2+1=3
        for(int i = 1; i <= maxDigit; i++)
        {
            c[i] += (a[i] + carry);
            carry = c[i]/10;
            c[i] %= 10;
        }
    }
    
    //求阶乘
    void fact(int *a,int num)
    {
        int carry = 0; // 进位
        for(int i=1; i <= maxDigit; i++)
        {
            // 从高位往低位存储数据,比如5!=120,则a[4]=a[5]=...=0,a[3]=1,a[2]=2,a[1]=0
            a[i] = a[i] * num + carry;
            carry = a[i] / 10;
            a[i] %= 10;
        }
    }
    
    int main()
    {
        int n;
        cin >> n;
        a[1] = 1;
        for(int i=1;i<=n;i++)
        {
            fact(a, i);
            add(a, c);
        }
    
        bool flag = false; // 当碰到第一个非0时,更新为true
        for(int i = 1000; i >= 1; i--)
        {
            // 左边的0不要打印出来,从第一个非0数字开始打印
            // 比如000……000120,打印出120
            if(c[i] != 0)
            {
                flag = true;
            }
    
            if(flag)
            {
                cout << c[i];
            }
        }
    
        return 0;
    }
    View Code

    P1007 独木桥

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int main()
    {
        int n,l,p,maxT=0,minT=0;
        scanf("%d%d",&l,&n);
    
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&p);
            maxT=max(maxT,max(l+1-p,p));
            minT=max(minT,min(l+1-p,p));
        }
    
        printf("%d %d",minT,maxT);
    
        return 0;
    }
    View Code

    P1002 过河卒

    #include<iostream>
    using namespace std;
    
    long long a[30][30]={0},n,m,my,mx;
    
    int main()
    {
        cin >> n >> m >> my >> mx;//输入数据
    
        // 整个棋盘往右往下挪两格,这样马处于原点(挪移后
        // 变成(2,2)点,往左上方跳不会出现数组越界的情况
        n += 2; // n行
        m += 2; // m列
        my += 2;// 马位于第几行
        mx += 2;// 马处于第几列
    
        for(int r = 2; r <= n; r++) // 共有n+1行
        {
            for(int c = 2; c <= m; c++) // 共有m+1列
            {
                a[r][c] = a[r - 1][c] + a[r][c - 1]; // 左侧的数 + 上方的数
                a[2][2]=1;  // 要初始化为1,若为0后面全是0
    
                // 马的9个控制点
                a[my][mx]=0;// 马本身的位置
                a[my + 2][mx + 1]=0;
                a[my + 2][mx - 1]=0;
                a[my - 2][mx + 1]=0;
                a[my - 2][mx - 1]=0;
                a[my + 1][mx + 2]=0;
                a[my + 1][mx - 2]=0;
                a[my - 1][mx + 2]=0;
                a[my - 1][mx - 2]=0;
            }
        }
    
        cout <<a[n][m];
    
        return 0;
    }
    View Code
  • 相关阅读:
    第十五节课:习题讲解
    第十四节课:字典
    Python第十三节课-文件的读取和写入
    Python第十二节课--循环语句与注释
    Python第十一节课--字符串的格式化
    Python第十节课==对象的方法
    Python第九节课--初识函数
    初识函数--文件的读取和打开,已一节课一节课分开,可不看
    刷题647. Palindromic Substrings
    刷题617. Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/alan-blog-TsingHua/p/10865507.html
Copyright © 2020-2023  润新知