西安电子大学计算机考研复试机试(2019)+ 2009年真题【完数+方阵求和+字符串提取数字求最大质

2019-04-14 16:32发布

牛客网 2009 problemA 本题是要求【a,b】范围中的完数,也就是6=1+2+3;除了该数本身的其他因子之和等于该数就是完数。 大部分人能写出这个程序,在自己的编辑器上都能通过。但是牛客网的测试样例都很大,本题我一开始按照下面的程序写的,超时不能通过。后来发现1-10000内的完数就4个,大家都直接拿这四个数来做一些判断得到答案,算是一种偷分的方法吧。 后来终于发现了下面这个方法,还是和之前求素数的时候一样,把求一个素数的时间复杂度从O(n/2)降到O(根号n)。 比如说28,只需要从2判断到5即可。后面的大因数(7,14),也就是28除以小因数(2,4)的商。 /* 2009 A [a,b]完数 6 = 1+2+3 */ #include using namespace std; int mark[100001]={0}; int len=0; void wan(){ for(int j=6;j<9999;j++){ int sum = 1; // 最最最关键的for循环 for(int i=2;i*i<=j;i++){ if(j%i==0){ sum = sum+i+(j/i); } } if(sum == j){ mark[len++]=j; } } } int main(){ int a,b; wan(); while(cin>>a>>b){ for(int i=0;i=a&&mark[i]<=b){ cout< /* 2009 A [a,b]完数 6 = 1+2+3 */ #include using namespace std; bool wan(int n){ int sum = 0; for(int i=1;i<=n/2;i++){ if(n%i==0){ sum+=i; } } if(sum == n){ return true; }else{ return false; } } int main(){ int a,b; cin>>a>>b; for(int i= a;i<=b;i++){ if(wan(i)){ cout< 牛客网 2009 problemB /* 2009 B m阶方阵(1,10) 每行每列及对角线元素之和 从大到小排列 用例1: 4 15 8 -2 6 31 24 18 71 -3 -9 27 13 17 21 38 69 */ #include #include #include using namespace std; bool cmp(int a,int b){ return a>b; } int main(){ int n; cin>>n; int a[n][n]; vector b; for(int i = 0;i>a[i][j]; } } // 求行列元素的和 for(int i = 0 ;i::iterator it = b.begin(); for(;it!=b.end();it++){ cout<<*it<<" "; } return 0; } 牛客网链接2009 problem C /** 2009 C 从字符串中提取出所有的数字字符拼接成无符号整数 输出该整数的最大因子,素数的话输出本身 样例: 3 sdf0ejg3.f?9f ?4afd0s&2d79*(g abcde 输出 13 857 0 */ #include #include using namespace std; const int maxn = 101; // 提取数字 int pull(string str){ int num = 0; int len =str.length(); for(int i=0;i='0'&&str[i]<='9'){ num = num *10 +str[i]-48; } } return num; } // 求出最大因子 int max_factor(int num){ int factor= 1,i=2; for(;i*i<=num;i++){ while(num%i==0){ num/=i; factor = i; } } if(num!=1) factor = num; return factor; } int main(){ int n; cin>>n; char str[maxn]; for(int i =0;i>str; cout< 牛客网链接:2009 problemD 思想:通过中序遍历和先序遍历来构建一棵树,然后再后序遍历读取该tree. 先序的第一个字符肯定是数根root结点,运用递归的思想,在中序遍历中找到该节点,并以此结点为分界线得到这棵树的左子树和右子树,然后递归建树就可以啦。 本题一直没检查出来的错误是:后序遍历函数和变量重名了,哎呀!还研究了半天结构体指针!! /* 2009 D 已知二叉树的先序和中序序列,输出后序遍历序列 方法:重建树,输出后序遍历 ABDGCEFH DGBAECHF */ #include #include #include using namespace std; const int maxn = 101; // 树的结构 struct BTree{ BTree *left; BTree *right; char val; BTree(char ch){ val = ch; left = right = NULL; } }; // 按照先序和中序进行重建二叉树 BTree* reConstructBinaryTree(string preorder,string inorder){ BTree* node = new BTree(preorder[0]); int len = preorder.length(); if(len == 0 || inorder.length()==0 ){ return NULL; } int i = inorder.find(preorder[0]); // string 提供的find方法很好用 // for(int i=0;ileft = reConstructBinaryTree(preorder.substr(1,i),inorder.substr(0,i)); node->right = reConstructBinaryTree(preorder.substr(i+1,len-i-1),inorder.substr(i+1,len-i-1)); // } // } return node; } // 后序遍历 void post_order(BTree* root){ if(root == NULL){ return; } post_order(root->left); post_order(root->right); cout<val; } int main(){ string preorder,inorder; while(cin>>preorder>>inorder){ BTree* tree = reConstructBinaryTree(preorder,inorder); post_order(tree); cout< 牛客网链接:2009 problemE 括号匹配问题数据结构课本中详细讲过,遍历读取所输入的字符串,如果是左括号,将其压栈,如果读到右括号,判断栈是否为空并且是否和栈顶元素匹配,如果符合条件,那么就将栈顶出栈,并继续判断。直到遍历完整个字符串,也就是for循环执行完毕,判断栈是否为空,如果是空,则说明已经完全匹配上啦。 要注意的一个点就是,其他元素不需要全都入栈,一开始我把表达式中的变量和常量都考虑进去了,程序就会变得很麻烦,并且做了很多无用功。读取到右括号的时候,需要将不是相应左括号的元素一一弹出栈,需要一个小的循环判断。。。 /* 2009 E 括号匹配判定 cin:n;n条表达式 cout:yes/no */ #include #include #include using namespace std; const int maxn =1001; stack st; // 表达式中的常量和变量不需要管,本题只要括号匹配即可 bool judge(char a[],int n){ for(int i=0;i>n; for(int i=0;i>str; while(!st.empty()){ st.pop(); } if(judge(str,strlen(str))==true){ cout<<"yes"<