【有奖】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]!='\0'){
        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]!='\0';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;
}

 

posted @ 2016-10-16 21:38  神犇(shenben)  阅读(901)  评论(0编辑  收藏  举报