• 【有奖】NOIP普及组模拟赛 个人邀请赛 乐多赛


    题目描述

    日本数学家角谷有一个猜想:任意一个自然数,经过以下过程,最终会得到1。现在请你打印出任意一个数使用角谷猜想转换为1需要几次。

    演变方式:

    1.如果这个数为奇数,则将它×3+1。如果这个数为偶数,则将它÷2。

    2.当这个数为1时,结束计算。

    输入输出格式

    输入格式:

    输入共1行。

    第1行:a,代表演变前的数。

    输出格式:

    一个自然数n,表示需要n次才能用角谷猜想把这个数变成1

    输入输出样例

    输入样例#1:
    8
    输出样例#1:
    3

    说明

    数据可能很大,要用高精度

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define N 200500
    int num[N]={1};
    int n,m,len=1;
    char s[N];
    unsigned long long tot=0;
    void mul(int k){
        for(int i=1;i<=len;i++){
            num[i]*=k;
            if(i>1){
                num[i]+=num[i-1]/10;
                num[i-1]%=10;
            }
            
        }  
        for(;num[len]>=10;len++){
            num[len+1]=num[len]/10;
            num[len]%=10;
        }
    }
    void div(int k){
        int d=0;
        for(int i=len;i;i--){
            d=d*10+num[i];
            num[i]=d/k;
            d%=k;
        }
        while(!num[len]) len--;
    }
    void add1(){
        int t=1;
        num[1]+=1;
        while(num[t]>9) num[t+1]+=num[t]/10,num[t]%=10,t++;
        if(t>len) len=t;
    }
    bool judge(){
        if(len==1&&num[1]==1) return 1;
        return 0;
    }
    bool odd(){
        return num[1]&1;
    }
    void dfs(){
        if(judge()) return ;
        if(odd()) mul(3),add1();
        else div(2);
        tot++;
        dfs();
    }
    int main(){
        cin>>s;
        int p=0;
        len=strlen(s);
        for(int i=len-1;i>=0;i--) num[++p]=s[i]-'0';
        dfs();
        cout<<tot;
        return 0;
    }

     U5190 去除多余括号

      • 0通过
      • 56提交
    • 题目提供者huangxuanao
    • 标签
    • 难度尚无评定

      

    最新讨论

    • 暂时没有讨论

    题目描述

    有一个四则运算的表达式(+、-、*、/),它可能有一些多余的括号可以去掉。把这些括号去掉的条件是:可以改变运算顺序,只要表达式计算结果不变即可(每去掉一组括号都不能使结果变化)。现在请你输出去掉多余括号的表达式。

    输入输出格式

    输入格式:

    一个表达式

    输出格式:

    去掉所有多余括号的表达式

    输入输出样例

    输入样例#1:
    a+(b-c)
    输出样例#1:
    a+b-c
    输入样例#2:
    1+2*3
    输出样例#2:
    1+2*3

    说明

    数据保证所有的括号合法,表达式长度不超过100个字符

    #include<string>
    #include<iostream>
    using namespace std;
    inline bool isOperator(char c){
        return c=='+'||c=='-'||c=='*'||c=='/';
    }
    bool allMulOrDiv(const string& exp){
        for(int i=0,len=exp.size();i<len;++i){
            if(exp[i]=='('){
                int cnt=1;
                for(++i;true;++i){
                    if(exp[i]=='(') ++cnt;
                    else if(exp[i]==')'){
                        --cnt;
                        if(!cnt) break;
                    }
                }
                ++i;
            }
            if(exp[i]=='+'||exp[i]=='-') return false;
        }
        return true;
    }
    int findMatchedLeft(const string& exp,int r){
        int countOfRight=1;
        for(--r;r>=0;--r){
            if(exp[r]==')') ++countOfRight;
            else if(exp[r]=='('){
                --countOfRight;
                if(!countOfRight) break;
            }
        }
        return r;
    }
    string& simplify(string& exp){
        int left,right=0;
        char head,tail,can;
        while((right=exp.find(')',right))!=string::npos){
            left=findMatchedLeft(exp,right);
        //get info
            if(left&&isOperator(exp[left-1])) head=exp[left-1];
            else head='+';
            if(right+1<exp.size()&&isOperator(exp[right+1])) tail=exp[right+1];
            else tail='+';
        //analyze
            if(right-left==2) can=1;
            else if(head=='/') can=0;
            else if(head=='*'||head=='-') can=allMulOrDiv(exp.substr(left+1,right-left-1));
            else can=tail=='+'||tail=='-'||allMulOrDiv(exp.substr(left+1,right-left-1));
        //process
            if(can){
                exp.erase(left,1).erase(right-1,1);
                --right;
            }
            else ++right;
        }
        return exp;
    }
    int main(){
        string exp; 
        getline(cin,exp);
        cout<<simplify(exp);
        return 0;
    }

    更正AC代码:

    #include<cstdio>
    using namespace std;
    int hasExcess(char s[],int leftBracket,int rightBracket){
        int i,leftAcount;
        //判断"-(a+b)"类型 
        if(s[leftBracket-1]=='-'){
            i=leftBracket;
            leftAcount=1;
            while(++i<rightBracket){
                if(s[i]=='(') leftAcount ++;
                if(s[i]=='+'&&leftAcount==1)  return 0;
            }
        }
        if(s[leftBracket-1]=='/') return 0;    
        //判断"加或减(a 任意 b)加或减"类型 
        if(s[leftBracket-1]!='*'&&s[leftBracket-1]!='/'&&s[rightBracket+1]!='*'&&s[rightBracket+1]!='/') return 1;
        //判断"*(a*b)乘或除以"类型  
        i=leftBracket;
        leftAcount=1;
        while(++i<rightBracket){
            if(s[i]=='(') leftAcount ++;
            if(s[i]=='*'&&leftAcount==1)  return 1;
        }
        return 0;
    }
    int delExcessBracket(char s[],int index){
        int leftBracket,rightBracket;
        while(s[index]!=''){
            if(s[index]==')') return index;
            if(s[index]=='('){
                leftBracket=index;
                index=rightBracket=delExcessBracket(s,index+1);
                if(hasExcess(s,leftBracket,rightBracket))
                    s[leftBracket]=s[rightBracket]=' ';
            }
            index++;
        }
    }
    int main(){
        char str[100];
        scanf("%s",str);
        delExcessBracket(str,0);
        for(int i=0;str[i]!='';i++) if(str[i]!=' ') printf("%c",str[i]);
        return 0;
    }

    U5191 小偷的背包

      • 0通过
      • 79提交
    • 题目提供者huangxuanao
    • 标签
    • 难度尚无评定

      

    最新讨论

    • 暂时没有讨论

    题目描述

    小偷的背包问题,大家知道是0-1背包问题。只是每件将要偷的物品的重量和价值都是带有1位小数的实数。小偷的背包可以装入物品的最大重量也是带有1位小数。

    输入输出格式

    输入格式:

    两个数m (小偷背包的承重)和 n(物品件数) (1.0<=m<=100.0, 1<=n<=20)

    以下是n行是每件物品的重量和价值。

    输出格式:

    最大价值。(带有1位小数,如果是整数,请输出 XXX.0)

    输入输出样例

    输入样例#1:
    34.5  3
    12.4  21.5
    15.3  18.4
    20.2  10.2
    输出样例#1:
    39.9

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=1e4+10;
    int n;
    double m,v[N],c[N],f[N]; 
    int main(){
        scanf("%lf%d",&m,&n);
        int V=m*10;
        for(int i=1;i<=n;i++) scanf("%lf%lf",&v[i],&c[i]),v[i]*=10,c[i]*=10;
        for(int i=1;i<=n;i++){
            for(int j=V;j>=v[i];j--){
                f[j]=max(f[j],f[j-(int)v[i]]+c[i]);
            }
        }
        f[V]/=10;
        printf("%.1lf",f[V]);
        return 0;
    }

    U5215 不同的二叉树

      • 0通过
      • 119提交
    • 题目提供者huangxuanao
    • 标签
    • 难度尚无评定

      

    最新讨论

    • 暂时没有讨论

    题目描述

    由n个节点可组成多少个不同的二叉树?

    输入输出格式

    输入格式:

    一个正整数n。

    输出格式:

    不同的二叉树的个数。

    输入输出样例

    输入样例#1:
    1
    输出样例#1:
    1

    说明

    测试数据规模:

    保证40%的数据n<=35;

    保证100%的数据n<=5000。

    保证120%的数据n<=10000。

    #include<cstdio>
    #include<cmath>
    int a[5005][5005],b[5005],n;
    void catalan()
    {
        int i,j,len,digit,t;
        a[1][0]=b[1]=len=1;
        for(i=2;i<=n;i++)
        {
            for(j=0;j<len;j++)
                a[i][j]=a[i-1][j]*(4*(i-1)+2);
            digit=0;
            for(int j=0;j<len;j++){
                t=a[i][j]+digit;
                a[i][j]=t%10;
                digit=t/10;
            }
            while(digit){
                a[i][len++]=digit%10;
                digit/=10;
            }
            digit=0;
            for(int j=len-1;j>=0;j--){
                t=digit*10+a[i][j];
                a[i][j]=t/(i+1);
                digit=t%(i+1);
            }
            while(!a[i][len-1])len--;
            b[i]=len;
        }
    }
    int main(){
        scanf("%d",&n);
        catalan();
        for(int i=b[n]-1;i>=0;i--) printf("%d",a[n][i]);
        return 0;
    }

     更正AC代码:

    #include<cstdio>
    using namespace std;
    const int N=1e6+10;
    int n,len;
    int f[N];
    void mul(int x){
        for(int i=1;i<=len;i++) f[i]*=x;
        for(int i=1;i<=len;i++){
            f[i+1]+=f[i]/10;
            f[i]=f[i]%10;
        }
        while(f[len+1]){
            f[len+2]=f[len+1]/10;
            f[len+1]%=10;
            len++;
        }
    }
    void div(int x){
        for(int i=len;i>=1;i--){
            f[i-1]+=f[i]%x*10;
            f[i]/=x;
        }
        for(int i=len;i>=1;i--)if(f[i]){len=i;break;}
    }
    int main(){
        scanf("%d",&n);
        f[len=1]=1;
        for(int i=1;i<=n;i++)mul(4*i-2),div(i+1);
        for(int i=len;i;i--) printf("%d",f[i]);
        return 0;
    }
  • 相关阅读:
    汇编语言-端口和外中断
    汇编语言-标志寄存器
    汇编程序-更灵活的定位内存地址方法
    汇编语言-[BX]和loop指令
    汇编语言-环境安装及各个寄存器介绍
    读书笔记-原码, 反码, 补码 详解
    读书笔记-整洁代码编写
    iOS-SQLite数据库使用介绍
    JSP-tag文件使用介绍
    【】maven 配置启动tomcat版本,修改默认的6.x.x版本
  • 原文地址:https://www.cnblogs.com/shenben/p/5967837.html
Copyright © 2020-2023  润新知