题目描述
日本数学家角谷有一个猜想:任意一个自然数,经过以下过程,最终会得到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; }
题目描述
有一个四则运算的表达式(+、-、*、/),它可能有一些多余的括号可以去掉。把这些括号去掉的条件是:可以改变运算顺序,只要表达式计算结果不变即可(每去掉一组括号都不能使结果变化)。现在请你输出去掉多余括号的表达式。
输入输出格式
输入格式:一个表达式
输出格式:去掉所有多余括号的表达式
输入输出样例
输入样例#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; }