student. a am I I'm a Freshman and I like JOBDU!
I am a student. JOBDU! like I and Freshman a I'm
#include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; //先将所有字符倒置,然后对单个字符倒置 int main() { string str; while (getline(cin,str)) { reverse(str.begin(),str.end());//将整个字符串倒置 int nBegin = 0, nEnd = 0; char ch = ' '; int pos = 0; while (true) { //找出即将进行部分倒置的字符串的起始位置到该子字符串后的空格位置 if (pos==0)//第一次起始位置在0处 nBegin = pos; else//以后的位置在前一个空格下一个位置开始才是下一个字符的起始位置 nBegin = pos+1; pos = str.find(ch,pos+1);//从空格的下一个位置找到新空格的位置 if (pos == std::string::npos)//如果是末尾,直接倒置 { reverse(str.begin() + nBegin, str.end()); break; } nEnd = pos; //部分倒置 reverse(str.begin() + nBegin, str.begin() + nEnd);//将整个子字符串倒置 } cout << str << endl; } return 0; } /************************************************************** Problem: 1361 User: EbowTang Language: C++ Result: Accepted Time:150 ms Memory:1520 kb ****************************************************************/
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
每个测试案例包括3行:
第一行为1个整数n(1<=n<=100000),表示序列的长度。
第二行包含n个整数,表示栈的压入顺序。
第三行包含n个整数,表示栈的弹出顺序。
对应每个测试案例,如果第二个序列是第一个序列的弹出序列输出Yes,否则输出No。
51 2 3 4 54 5 3 2 151 2 3 4 54 3 5 1 2
YesNo
#include <iomanip>//小数点精确 #include <stdio.h> #include "vector" #include "string" #include "algorithm" #include <iostream> using namespace std; class Stack { public: Stack(int size) { elements = new int[size]; top = -1; } ~Stack() { delete[] elements; elements = NULL; } bool push(int ndata);//压入元素到栈顶 void popTop();//弹出栈顶元素 int getTop(); bool empty(); private: int *elements; int top; //始终指向栈顶,top=0,就表示有一个数据了 }; //压入元素 bool Stack::push(int ndata) { top++; elements[top] = ndata;//从栈顶压入元素 return true; } bool Stack::empty() { if (top == -1) return true; else return false; } int Stack::getTop() { if (top > -1) return elements[top]; } //除去栈顶元素 void Stack::popTop() { if (top > -1) top--; } int main() { int n = 0; while (cin>>n) { //重新按照第一组数据入栈,每次入栈后都检查下是否跟出栈顺序内容相同, //如果相同,则立马出栈。否则暂时不作处理 //然后,将栈顶的元素与相应的出栈顺序比较,如果相同则出栈, //最后如果这个栈内不存在元素,则证明第二个序列为出栈序列。 Stack s1(1000); vector<int> avec(n), bvec(n); for (int i = 0; i < n; i++) cin >> avec[i]; for (int i = 0; i < n; i++) cin >> bvec[i]; int i = 0, j = 0; while (i<n) {//入栈操作,如果相同就出栈 s1.push(avec[i]); if (s1.getTop() == bvec[j]) { j++; s1.popTop(); } i++; } //对栈中剩余的元素进行出栈操作 while (j<n) { if (s1.getTop() == bvec[j]) s1.popTop(); j++; } if (s1.empty()) cout << "Yes" << endl; else cout << "No" << endl; } } /************************************************************** Problem: 1366 User: EbowTang Language: C++ Result: Wrong Answer ****************************************************************/
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
每个测试案例包括n+1行:
第一行为2个整数n,k(1<=n<=10000),n表示结点的个数,k表示要求的路径和,结点编号从1到n。
接下来有n行。这n行中每行为3个整数vi,leftnode,rightnode,vi表示第i个结点的值,leftnode表示第i个结点的左孩子结点编号,rightnode表示第i个结点的右孩子结点编号,若无结点值为-1。编号为1的结点为根结点。
对应每个测试案例,先输出“result:”占一行,接下来按字典顺序输出满足条件的所有路径,这些路径由结点编号组成,输出格式参照输出样例。
5 2210 2 35 4 512 -1 -14 -1 -17 -1 -11 51 -1 -1
result:A path is found: 1 2 5A path is found: 1 3result:
#include "queue" #include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; // 节点定义 class BSTNode { public: BSTNode()// 默认构造 { pRight = NULL; pLeft = NULL; value = 0; count = 0; } friend class LinkBST;// 允许链表类随意访问节点数据 private: int value; BSTNode *pRight; BSTNode *pLeft; int count; }; // 不带头结点的二叉树定义 class LinkBST { public: LinkBST(int size) { m_pNode = new BSTNode[size + 1]; } ~LinkBST() { delete[] m_pNode; m_pNode = NULL; } // 连接节点集(形成一棵树) void LinkBSTNode(int nValue ,int lnode, int rnode, int pos); void FindTPathSum(BSTNode *pRoot, const int exNum, vector<int>& path, int &curNum); void FindPath(BSTNode *&pRoot, int exceptionNum); // 节点集 BSTNode *m_pNode; }; //用前序遍历的方式搜索路劲 void LinkBST::FindTPathSum(BSTNode *pRoot,const int exNum, vector<int>& path, int &curNum) { curNum += pRoot->value; path.push_back(pRoot->count); //如果pRoot是叶节点,并且路径上节点的值的和等于输入的值 //打印这条路径 bool isLeaf = (pRoot->pLeft == NULL) && (pRoot->pRight == NULL); if (isLeaf && curNum == exNum) { cout << "A path is found: "; vector<int>::iterator iter = path.begin(); for (; iter != path.end(); iter++) cout << *iter << " "; cout << endl; } //如果pRoot不是叶节点,则遍历其子节点 if (pRoot->pLeft != NULL) FindTPathSum(pRoot->pLeft, exNum, path, curNum); if (pRoot->pRight != NULL) FindTPathSum(pRoot->pRight, exNum, path, curNum); //在返回到父节点之前,在路径上删除当前pRoot节点的count curNum -= pRoot->value; path.pop_back(); } void LinkBST::FindPath(BSTNode *&pRoot, int exceptionNum) { if (pRoot == NULL) return; vector<int> vecpath; int currentNum = 0; FindTPathSum(pRoot, exceptionNum, vecpath, currentNum); } // 连接节点集(形成一棵树) void LinkBST::LinkBSTNode(int nValue, int lnode, int rnode, int pos) { m_pNode[pos].value = nValue; m_pNode[pos].count = pos; if (lnode != -1) m_pNode[pos].pLeft = &m_pNode[lnode]; if (rnode != -1) m_pNode[pos].pRight = &m_pNode[rnode]; } int main() { int n = 0, exSum = 0; while (cin >> n >> exSum) { BSTNode *pRoot = NULL; LinkBST bst(n); pRoot = &bst.m_pNode[1];//指向根节点 int value = 0, nleftnode = 0, nrightnode = 0; //插入节点,建立连接 for (int i = 1; i <= n; i++) { cin >>value>> nleftnode >> nrightnode; if (nleftnode>n || nrightnode > n) exit(1); bst.LinkBSTNode(value,nleftnode, nrightnode, i);//第i个节点指向第nleftnode个节点和第nrightnode节点 int a = 0; } cout << "result:" << endl; bst.FindPath(pRoot,exSum); } } /************************************************************** Problem: 1368 User: EbowTang Language: C++ Result: Wrong Answer ****************************************************************/
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
每个测试案例包括2行:
第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。
第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。
对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。
8 44 5 1 6 2 7 3 8
1 2 3 4
C++程序实现如下:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
对应每个测试案例,
输出”Yes”代表在二维数组中找到了数字t。
输出”No”代表在二维数组中没有找到数字t。
3 351 2 34 5 67 8 93 312 3 45 6 78 9 103 3122 3 45 6 78 9 10
YesNoNo
#include <cstdio> int m, n; int t; int a[1000][1000]; void getRes() { int row = 0, col = n - 1; while (col >=0 && row < m) { if (a[row][col] > t) { --col; } else if (a[row][col] < t) { ++row; } else { printf("Yes\n"); return; } } printf("No\n"); } int main() { while (scanf("%d %d", &m, &n) != EOF) { scanf("%d", &t); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { scanf("%d", &a[i][j]); } } getRes(); } return 0; } /************************************************************** Problem: 1384 User: EbowTang Language: C++ Result: Accepted Time:680 ms Memory:4928 kb ****************************************************************/
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点个数。
输入的第二行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的前序遍历序列。
输入的第三行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的中序遍历序列。
对应每个测试案例,输出一行:
如果题目中所给的前序和中序遍历序列能构成一棵二叉树,则输出n个整数,代表二叉树的后序遍历序列,每个元素后面都有空格。
如果题目中所给的前序和中序遍历序列不能构成一棵二叉树,则输出”No”。
81 2 4 7 3 5 6 84 7 2 1 5 3 8 681 2 4 7 3 5 6 84 1 2 7 5 3 8 6
7 4 2 5 8 6 3 1 No
#include "string" #include "vector" #include "iostream" using namespace std; int count_node; typedef struct _Node { int value; struct _Node *pRight; struct _Node *pLeft; }Node; int findPos(const vector<int> &vec, int a) { if (vec.size()==0) return -1; for (int i = 0; i < vec.size();i++) { if (vec[i]==a) return i; } return -2; } //Tips: //int *a;int * &p = a; //很容易理解,把 int * 看成一个类型,a就是一个整型指针,p 是a的别名,那么a与p就完全等同了 void ReBuildBST(const vector<int> &preVec, const vector<int> &midVec, Node *&proot) {//注意:proot是引用,要不然函数返回会对proot的内容进行撤销 if (preVec.size() == 0) return; proot = new Node; proot->value = preVec[0];//prestr[0]肯定是当前二叉树的根 proot->pLeft = NULL; proot->pRight = NULL; count_node++; if (preVec.size() == 1) return; //因为是互不相同的数据,所以直接判断prevec中的每一个数据是否一定能在midvec找到即可 for (int i = 0; i < preVec.size();i++) { bool flag = false; for (int j = 0; j < midVec.size();j++) { if (preVec[i] == midVec[j]) flag = true; } if (flag==false) return; } int k = findPos(midVec,preVec[0]); vector<int> preLeft(preVec.begin() + 1, preVec.begin() + k + 1); vector<int> midLeft(midVec.begin(), midVec.begin() + k); ReBuildBST(preLeft, midLeft, proot->pLeft); vector<int> preRight(preVec.begin()+ k + 1, preVec.end()); vector<int> midRight(midVec.begin()+ k + 1, midVec.end()); ReBuildBST(preRight, midRight, proot->pRight); } void postOrder(Node * root) { if (root != NULL){ postOrder(root->pLeft); postOrder(root->pRight); cout << root->value<<" "; } } int main() { int N = 0; while (cin >> N) { count_node = 0; vector<int> preVec(N,0), midVec(N,0); for (int i = 0; i < N; i++) cin >> preVec[i]; for (int i = 0; i < N; i++) cin >> midVec[i]; Node *pRoot=NULL; ReBuildBST(preVec, midVec, pRoot); if (count_node == N) { postOrder(pRoot); cout << endl; } else { cout << "No" << endl; } count_node=0; } } /************************************************************** Problem: 1385 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb
输入可能包含多个测试样例,对于每个测试案例,
输入包括一个整数n(1<=n<=70)。
对应每个测试案例,
输出第n项斐波那契数列的值。
3
2
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; int main() { int n; while (cin>>n && n >= 1&& n <= 70) { vector<long long> vec(71,0); vec[0] = 0; vec[1] = 1; for (int i = 2; i <= n; i++) vec[i] = vec[i - 1] + vec[i-2]; cout << vec[n]<<endl; } return 0; } /************************************************************** Problem: 1387 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
输入可能包含多个测试样例,对于每个测试案例,
输入包括一个整数n(1<=n<=70)。
对应每个测试案例,
输出该青蛙跳上一个n级的台阶总共有多少种跳法。
5
8
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; //当n=1时,ans=1,当n=2时,ans=2 //当n=3时,ans=3,当n=4时,ans=5 //当n=5时,ans=8 //令跳到第i个台阶时的方法数为f(i) //当我们确定选择下一步跳2时,方法数就是f(i-1)(此时步数i-1+2=i+1) //当我们确定选择下一步跳1时,方法数就是f(i) //显然两种选择都可以,所以f(i+1)=f(i)+f(i-1) int main() { int n; while (cin >> n) { vector<long long> vec(n+1); vec[1] = 1; vec[2] = 2; for (int i = 3; i <= n; i++) { vec[i] = vec[i - 1] + vec[i-2]; } cout << vec[n] << endl; } return 0; } /************************************************************** Problem: 1388 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
输入可能包含多个测试样例,对于每个测试案例,
输入包括一个整数n(1<=n<=50)。
对应每个测试案例,
输出该青蛙跳上一个n级的台阶总共有多少种跳法。
6
32
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; //当n=1时,ans=1,当n=2时,ans=2 //当n=3时,ans=4,当n=4时,ans=8 //令跳到第i个台阶时的方法数为f(i) //当我们确定选择下一步跳1时,方法数就是f(i) //当我们确定选择下一步跳2时,方法数就是f(i-1) //当我们确定选择下一步跳3时,方法数就是f(i-2) //当我们确定选择下一步跳4时,方法数就是f(i-3) //....... //显然以上选择都可以,所以f(i+1)=f(i)+f(i-1)+........... int main() { int n; while (cin >> n) { vector<long long> vec(n + 1); vec[0] = 1; vec[1] = 1; vec[2] = 2; for (int i = 3; i <= n; i++) { int k = i; while (k > -1) vec[i] += vec[k--];//计算f(i+1)=f(i)+f(i-1)+........... } cout << vec[n] << endl; } return 0; } /************************************************************** Problem: 1389 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行包括两个整数m和n(1<=m,n<=1000):表示矩阵的维数为m行n列。
接下来的m行,每行包括n个整数,表示矩阵的元素,其中每个元素a的取值范围为(1<=a<=10000)。
对应每个测试案例,输出一行,
按照从外向里以顺时针的顺序依次打印出每一个数字,每个数字后面都有一个空格。
4 41 2 3 45 6 7 89 10 11 1213 14 15 16
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> using namespace std; //参考自《剑指offer》 void printMatrixInCircle(int *matrix, int row, int column, int start) { int endX = column - 1 - start; int endY = row - 1 - start; int i; //打印从左到右一行 for (i = start; i <= endX; i++) {//从start开始到endx cout<<matrix[start*column + i]<<" "; } //打印从上到下一列 if (endY > start) { for (i = start + 1; i <= endY; i++) { cout << matrix[i*column + endX] << " "; } } //打印从右到左一行 if (endY > start && endX > start) { for (i = endX - 1; i >= start; i--) { cout << matrix[endY*column + i] << " "; } } //打印从下到上一列 if (endX > start && endY > start + 1) { for (i = endY - 1; i >= start + 1; i--) { cout << matrix[i*column + start] << " "; } } } void printMatrix(int *matrix, int row, int column) { if (matrix == NULL || row <= 0 || column <= 0) return; int start = 0; while (row > start * 2 && column > start * 2) { printMatrixInCircle(matrix, row, column, start); start++; } cout << endl; } int main() { int m=0, n=0;//行 列 while (cin>>m>>n) { if (m <= 0 || n <= 0) break; int *matrix = new int[m*n]; if (!matrix) exit(-1); for (int i = 0; i < m*n; i++) cin>>matrix[i]; printMatrix(matrix, m, n); delete[] matrix; matrix = NULL; } return 0; } /************************************************************** Problem: 1391 User: EbowTang Language: C++ Result: Accepted Time:910 ms Memory:1520 kb ****************************************************************/
时间限制:2 秒
内存限制:32 兆
特殊判题:否
提交:474
解决:174
输入两个递增的序列,输出合并这两个序列后的递增序列。
每个测试案例包括3行:
第一行为1个整数n(1<=n<=1000000)表示这两个递增序列的长度。
第二行包含n个整数,表示第一个递增序列。
第三行包含n个整数,表示第二个递增序列。
对应每个测试案例,输出合并这两个序列后的递增序列。
41 3 5 72 4 6 8
1 2 3 4 5 6 7 8
#include "vector" #include <iostream> #include "fstream" #include "algorithm" #include <stdio.h> #include "string" #include <cmath> #include <cstdlib> #include "map" using namespace std; int main() { int n = 0; while (cin >> n, n > 0) { vector<int> nums1(n,0); vector<int> nums2(n,0); vector<int> ans(2*n, 0); for (int i = 0; i < n; i++) cin >> nums1[i]; for (int i = 0; i < n; i++) cin >> nums2[i]; //这道题没做对,但是思路的确是这样的,不知道错在哪里! int g = 0, h = 0; int i = 0; for (; i < 2 * n; i++) { if (g == n || h == n) break; if (nums1[g] < nums2[h]) ans[i] = nums1[g++]; else if (nums1[g] > nums2[h]) ans[i] = nums2[h++]; else{ ans[i] = nums1[g]; g++; h++; } } if (g < n) { while (g < n) ans[i++] = nums1[g++]; } if (h < n) { while (h < n) ans[i++] = nums2[h++]; } for (int j = 0; j < i-1; j++) cout << ans[j] << " "; cout <<ans[i-1]<< endl; } return 0; } /************************************************************** Problem: 1393 User: EbowTang Language: C++ Result: Output Limit Exceed ****************************************************************/
众所周知JOBDU旗下的JOBBALA公司是一家以个性、亲民著称的IT公司。在JOBBALA公司成立50周年的日子里,公司CEO组织全体员工登山旅游。按照往常的习惯,导游通常要求游客按照身高从低到高的顺序排好,但是考虑这次JOBBALA人数太多,排序很耗时间。因此,导游想了想,要求JOBBALA的员工可以随便排,但是必须保证队列的第一个是队列中最矮的,队列的最后一个是队列中最高的。例如:队列 { 1, 4, 3, 2, 2, 5} 就是符合的队列,{1, 4, 2, 3, 2, 5}也符合,而{2, 1, 2, 3, 4, 5}就是错的。请问对于任意的队列,最少要两两交换多少次,可以让其符合导游的要求?
输入有多组测试案例,每个测试案例为2行。
第一行包括一个整数n(2<=n<=200)表示人数,接下来一行包括n个整数a1, a2, …… an (1<=ai<=200) 表示n个员工初始的排列。
对应每个测试案例,按照导游的要求,输出最少需要两两交换的次数。
289 88455 88 1 2
13
#include <iostream> using namespace std; int main(){ int N,temp; while(cin>>N){ int minimum=300,maximum=-300,minI,maxI; for(int i=1;i<=N;++i){ cin>>temp; if(minimum>temp) minimum=temp,minI=i; if(maximum<=temp) maximum=temp,maxI=i; } int result=minI-1+N-maxI; if(minI>maxI) result--; cout<<result<<endl; } } /************************************************************** Problem: 1398 User: EbowTang Language: C++ Result: Accepted Time:570 ms Memory:1520 kb ****************************************************************/
#include <stdio.h> #include <iostream> #include <bitset> using namespace std; //二进制数bits的长度为1000001 bitset<1000001> bits;//出现一次将被置1,再出现将被置零,始终保留并记录只出现一次的数 bitset<1000001> bits_assit;//出现过一次将被置1,再出现不做处理 //如果某一个数只出现一次,那么必定在其该位置的二进制位必定为1,否则为0 int main() { int n; while (scanf("%d", &n) != EOF) { bits.reset();//全部置零 bits_assit.reset(); int count = 0;//统计出现一次的数的数量 for (int i = 1, temp = 0; i <= n; i++) { scanf("%d", &temp); if (!bits_assit[temp])//如果第一次出现(此时temp位置的二进制位为0) { bits.set(temp);//将此temp位置的二进制位设为1 bits_assit.set(temp); count++; } else if (bits_assit[temp])//如果已经出现过,将其位置的二进制位置零(总是保持出现过一次的才置1) { if (bits[temp]) { bits.reset(temp);//将此temp位置的二进制位设为0 count--; } } } bool first_time=true; printf("%d\n",count); if(!count){ continue; } for(int i=1;i<=1000000;i++){ if(bits[i]){ if(first_time){ first_time=false; }else{ putchar(' '); } printf("%d",i); } } putchar('\n'); } return 0; } /************************************************************** Problem: 1402 User: EbowTang Language: C++ Result: Accepted Time:1320 ms Memory:1764 kb ****************************************************************/