给出n个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合。
输入有多组,每组包含n(n<=600)和n个不同的整数,整数大于1且小于等于1000。
当n=0时,程序结束,不需要处理这组数据。
分析:
这是一个典型的最大公约数应用,显然真分数的分子和分母的最大公约数只能是1
每行输出最简真分数组合的个数。
7 3 5 7 9 11 13 15 3 2 4 5 0
17 2
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include "math.h" usingnamespace std; intEuclid(intmin, intmax) {//判断是否是真分数:依据就是最大公约数是1,那就是真分数 if(max == 0) returnmin; else returnEuclid(max,min%max); } intmain() { intn = 0; while(cin >> n) { if(n == 0) break; vector<int> vec(n); for(inti = 0; i < n; i++) cin >> vec[i]; sort(vec.begin(),vec.end()); intcount = 0; for(vector<int>::iterator it = vec.begin() + 1; it != vec.end(); it++) for(vector<int>::iterator jt = vec.begin(); jt != it; jt++) if(Euclid(*jt, *it)==1)//最大公约数是1,那么就是真分数 count++; cout << count << endl; } return0; } /************************************************************** Problem: 1465 User: EbowTang Language: C++ Result: Accepted Time:100 ms Memory:1520 kb ****************************************************************/
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include "math.h" using namespace std; bool isTrueFen(int min, int max) {//判断是否是真分数:依据就是从2开始是否有共同的约数 if (min == 1 && max > 1) return true; for (int i = 2; i <= min; i++) { if (min%i == 0 && max%i == 0) return false; } return true; } int main() { int n = 0; while (cin >> n) { if (n == 0) break; vector<int> vec(n); for (int i = 0; i < n; i++) cin >> vec[i]; sort(vec.begin(),vec.end()); int count = 0; for (vector<int>::iterator it = vec.begin() + 1; it != vec.end(); it++) { for (vector<int>::iterator jt = vec.begin(); jt != it; jt++) { if (isTrueFen(*jt, *it)) count++; } } cout << count << endl; } return 0; } /************************************************************** Problem: 1465 User: EbowTang Language: C++ Result: Time Limit Exceed ****************************************************************/
二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:
1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;
2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;
3. 左、右子树本身也是一颗二叉排序树。
现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。
输入包含多组测试数据,每组测试数据两行。
第一行,一个数字N(N<=100),表示待插入的节点数。
第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10^8。
输出共N行,每次插入节点后,该节点对应的父亲节点的关键字值。
5 2 5 1 3 4
-1 2 2 5 3
#include "queue" #include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; // 节点定义 class BSTNode { public: BSTNode(int newData )// 默认构造 { pRight = NULL; pLeft = NULL; pParent = NULL; value = newData; } ~BSTNode(); friend class LinkBST;// 允许链表类随意访问节点数据 private: int value; BSTNode *pRight; BSTNode *pLeft; BSTNode *pParent; }; // 有头结点的二叉搜索树定义 class LinkBST { public: LinkBST(){ m_pRoot = NULL; }; ~LinkBST(){}; BSTNode* getRoot() const { return m_pRoot; } // 插入节点 void InsertBTNode(int newData); private: BSTNode *m_pRoot; }; // 插入节点 void LinkBST::InsertBTNode(int newData) { BSTNode *newNode = new BSTNode(newData); if (m_pRoot == NULL) { m_pRoot = newNode; cout << "-1" << endl; return; } BSTNode *pPre = NULL;//用于保存上一个节点 BSTNode *pCur = m_pRoot; //寻找要插入的节点的位置 (一定是某个叶子) while (pCur != NULL) { pPre = pCur;//保存节点 if (newNode->value < pCur->value) pCur = pCur->pLeft;//较小值则移到节点的左子树 else if (newNode->value > pCur->value) pCur = pCur->pRight; } //建立连接 if (newNode->value < pPre->value) pPre->pLeft = newNode; else if (newNode->value > pPre->value) pPre->pRight = newNode; newNode->pParent = pPre; cout << newNode->pParent->value << endl; } int main() { int n = 0; while (cin >> n) { LinkBST bst; int val = 0; for (int i = 0; i < n; i++) { cin >> val; bst.InsertBTNode(val); } } return 0; } /************************************************************** Problem: 1467 User: EbowTang Language: C++ Result: Accepted Time:20 ms Memory:1520 kb ****************************************************************/
给定两个字符串S1和S2,合并成一个新的字符串S。
合并规则为,S1的第一个字符为S的第一个字符,将S2的最后一个字符作为S的第二个字符;
将S1的第二个字符作为S的第三个字符,将S2的倒数第二个字符作为S的第四个字符,以此类推。
包含多组测试数据,每组测试数据包含两行,代表长度相等的两个字符串S1和S2(仅由小写字母组成,长度不超过100)。
分析:
简单模拟题
合并后的新字符串S
abc def
afbecd
#include "string" #include <iostream> using namespace std; int main() { string str1,str2; while (cin>>str1>>str2) { int len1 = str1.size(); int len2 = str2.size(); string str(len1+len2,'0');//准备存放结果 int i = 0, j = 0; while (i < len1) { str[j] = str1[i++];//放在偶数下标的位置 j = j + 2; } i = len2 - 1, j = 1; while (i >= 0) { str[j] = str2[i--];//放在基数下标的位置 j = j + 2; } cout << str << endl; } return 0; } /************************************************************** Problem: 1471 User: EbowTang Language: C++ Result: Accepted Time:0 ms Memory:1520 kb ****************************************************************/
一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ...,aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中序列和最大为18,为子序列(1, 3, 5, 9)的和.
你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和为100,而最长上升子序列为(1, 2, 3)。
输入包含多组测试数据。
每组测试数据由两行组成。第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。
对于每组测试数据,输出其最大上升子序列和。
7 1 7 3 5 9 4 8
18
#include"iostream" #include <stdio.h> using namespace std; int data[1001]; int dp[1001];//第1个元素到第i个元素的最大不降和 int N = 0; int MaxLongNoDrop() { int max = -1; for (int i = 1; i <= N; ++i) { dp[i] = data[i]; for (int j = 1; j < i; ++j) { if (data[i] > data[j] && dp[i] < dp[j] + data[i]) { dp[i] = dp[j] + data[i]; if (max < dp[i]) max = dp[i]; } } } return max; } int main(void) { while (cin>>N) { for (int i = 1; i <= N; ++i) cin>>data[i]; cout << MaxLongNoDrop() << endl; } return 0; } /************************************************************** Problem: 1480 User: EbowTang Language: C++ Result: Accepted Time:40 ms Memory:1528 kb ****************************************************************/
输入N个(N<=10000)数字,求出这N个数字中的最大值和最小值。每个数字的绝对值不大于1000000。
输入包括多组测试用例,每组测试用例由一个整数N开头,接下去一行给出N个整数。
输出包括两个整数,为给定N个数中的最大值与最小值。
5 1 2 3 4 5 3 3 7 8
5 1 8 3
#include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; int main() { int n = 0; while (cin >> n, n > 0 && n <= 10000) { int tmp = 0; int maxnum = -10000; int minnum = 99999; for (int i = 0; i < n; i++) { cin >>tmp; if (maxnum < tmp) maxnum = tmp; if (minnum>tmp) minnum = tmp; } cout << maxnum << " " << minnum << endl; } } /************************************************************** Problem: 1483 User: EbowTang Language: C++ Result: Output Limit Exceed ****************************************************************/
计算两个矩阵的乘积,第一个是2*3,第二个是3*2
输入为两个矩阵,其中一个为2*3的矩阵,另一个为3*2的矩阵
一个2*2的矩阵(每一个数字后都跟一个空格)
1 2 3 3 4 5 6 7 8 9 10 11
52 58 100 112
#include<stdio.h> #include<stdlib.h> #include<string.h> int Matrix1[2][3]; int Matrix2[3][2]; int main () { int i,j,k; int row = 2,col = 3; while(scanf("%d %d %d",&Matrix1[0][0],&Matrix1[0][1],&Matrix1[0][2]) != EOF){ int Matrix3[2][2] = {0}; //输入第一个矩阵 for(i = 1;i < row;i++){ for(j = 0;j < col;j++){ scanf("%d",&Matrix1[i][j]); } } //输入第二个矩阵 for(i = 0;i < col;i++){ for(j = 0;j < row;j++){ scanf("%d",&Matrix2[i][j]); } } //相乘 for(i = 0;i < row;i++){ for(j = 0;j < row;j++){ for(k = 0;k < col;k++){ Matrix3[i][j] += Matrix1[i][k] * Matrix2[k][j]; } } } //输出 for(i = 0;i < row;i++){ for(j = 0;j < row;j++){ printf("%d ",Matrix3[i][j]); } printf("\n"); } } return 0; } /************************************************************** Problem: 1489 User: EbowTang Language: C++ Result: Accepted Time:0 ms Memory:1020 kb ****************************************************************/
不用strcat 函数,自己编写一个字符串链接函数MyStrcat(char dstStr[],charsrcStr[])
两个字符串,字符串由小写字母组成。
链接后的字符串
hello world good morning
helloworld goodmorning
#include "string" #include "algorithm" #include <iostream> using namespace std; int MyStrcat(char dstStr[], char srcStr[]) { char *pdst = dstStr; char *psrc = srcStr; int len1 = strlen(dstStr); int len2 = strlen(srcStr); int i, j; for ( i = len1, j = 0; j < len2; j++, i++) dstStr[i] = srcStr[j]; dstStr[i] = '\0'; return 0; } int main() { char src1[200] = {'\0'}, src2[100] = { '\0' }; while (cin>>src1>>src2) { MyStrcat(src1,src2); cout << src1 << endl; } return 0; } /************************************************************** Problem: 1490 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。
输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。
对于每组测试数据,输出为一个整数,表示a和b的公约数个数。
8 16 22 16
4 2
#include "stdio.h" #include <iostream> #include "vector" using namespace std; int EUCLID(int a, int b)//欧几里得算法计算最大公约数 { if (b == 0) return a; else return EUCLID(b, a%b); } int main() { int a, b; int i; while (cin >> a >> b) { int count = 0; int maxGcd = EUCLID(a, b);//把最大公约数计算出来 for (i = 1; i <= maxGcd; ++i) {//计算公共公约数 if (a%i == 0 && b%i == 0) count++; } cout << count << endl; } return 0; } /************************************************************** Problem: 1493 User: EbowTang Language: C++ Result: Time Limit Exceed ****************************************************************/
#include <iostream> #include "vector" using namespace std; int EUCLID(int a, int b)//欧几里得算法计算最大公约数 { if (b == 0) return a; else return EUCLID(b, a%b); } int main() { int a, b; int count; int i; while (cin >> a >> b) { count = 0; int maxGcd = EUCLID(a, b);//把最大公约数计算出来 for (i = 1; i * i < maxGcd; ++i) { if (maxGcd % i == 0) count += 2; } if (i * i == maxGcd) ++count; cout << count << endl; } return 0; } /************************************************************** Problem: 1493 User: EbowTang Language: C++ Result: Accepted Time:30 ms Memory:1520 kb ****************************************************************/
#include "vector" #include <iostream> #include "algorithm" #include<string> #include <stdio.h> #include<cmath> #include<cstdlib> using namespace std; //动态规划问题: //令dp[i]为在前i个项目下能获得的最大利润 //对于第i个项目,如果前面第j个项目满足时间条件,我们可以做,也可以不做 //如果不做第i个项目,那就不变,和前一次一样,dp[i]=dp[i-1](不是dp[i]) //如果做第i个项目,并且满足第j个项目时间,dp[i]=dp[j] + pro[i].value class Item { public: int st; int ed; int value; }; int cmp(Item x, Item y) { return x.ed<y.ed;//按照结束时间排序 } int main() { int n; while (scanf("%d", &n) != EOF) { vector<int> dp(n+1,0); Item pro[10001]; int i, j; for (i = 1; i <= n; i++) scanf("%d%d%d", &pro[i].st, &pro[i].ed, &pro[i].value); sort(pro+1, pro+n+1, cmp);//类似贪心处理 dp[1] = pro[1].value; for (i = 2; i <= n; i++) { for (j = i - 1; j >= 1; j--)//必须逆序 if (pro[j].ed <= pro[i].st)//只要第i个项目前面的某个项目满足条件 break; dp[i] = max(dp[j] + pro[i].value, dp[i - 1]); } printf("%d\n", dp[n]); } return 0; } /************************************************************** Problem: 1499 User: EbowTang Language: C++ Result: Accepted Time:260 ms Memory:1576 kb ****************************************************************/
#include "vector" #include <iostream> #include "algorithm" #include<string> #include <stdio.h> #include<cmath> #include<cstdlib> using namespace std; long long numbers[200]; string str_num[200]; //不能简单的按字典序排序即小的在前面。 //比如32的字典序比322小,但是32322比32232大, bool cmp(const string &str1, const string &str2) { string _str1 = str1; string _str2 = str2; _str1.append(str2);//在_str1后面追加str2字符串 _str2.append(str1); return _str1 < _str2;//true则将对原字符串顺序颠倒,否则不处理 } int main() { int n; while (scanf("%d", &n) != EOF) { //接受输入 for (int i = 0; i < n; i++) scanf("%d", numbers + i); for (int i = 0; i < n; i++) { char str[20]; sprintf(str, "%d", numbers[i]);//将数字转换到str内存中 str_num[i] = str; } sort(str_num, str_num + n, cmp); for (int i = 0; i < n; i++) cout << str_num[i]; cout << endl; } return 0; } /************************************************************** Problem: 1504 User: EbowTang Language: C++ Result: Accepted Time:220 ms Memory:1524 kb ****************************************************************/
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
输入可能包含多个测试样例。
对于每个测试案例,输入为一个整数n(1<= n<=100000)。
对应每个测试案例,
输出1+2+3+…+n的值。
3 5
6 15
#include <iostream> #include "algorithm" using namespace std; class BaseAdd; BaseAdd* Array[2];//两个基类指针 class BaseAdd { public: virtual int Sum(int n)//虚函数 { return 0;//递归截止条件 } }; class DerAdd :public BaseAdd { public: virtual int Sum(int n)//覆盖基类虚函数 { //当n=0时,Array[!!n]=Array[0],他存储的就是基类的对象地址,显然调用的是基类的Sum函数 //当n=1时,Array[!!n]=Array[1],他存储的是派生类的对象地址,将会调用派生类的函数 return Array[!!n]->Sum(n - 1) + n;//按题目要求实现“循环”只能用递归了 } }; int solutionSum(int n) { BaseAdd a; DerAdd b; Array[0] = &a; Array[1] = &b;//根据动态绑定,在程序运行时再确定具体调用哪一个函数 int nSum = Array[1]->Sum(n); return nSum; } int main() { int n = 0; while (cin >> n) cout << solutionSum(n) << endl; return 0; } /************************************************************** Problem: 1506 User: EbowTang Language: C++ Result: Accepted Time:880 ms Memory:1628 kb ****************************************************************/
#include <iostream> using namespace std; //错误的解法:使用递归 //参考http://blog.csdn.net/wusuopubupt/article/details/17714705 int add(int n, int *pSum) {//n==0就停止递归 n && add(n - 1, pSum);//递归(很遗憾当n=5000时就栈溢出了) return (*pSum += n);//实现计算 } int main() { int n = 0; while (cin>>n) { int sum = 0; add(n, &sum); cout << sum << endl; } return 0; } /************************************************************** Problem: 1506 User: EbowTang Language: C++ Result: Accepted Time:710 ms Memory:1820 kb ****************************************************************/
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
输入可能包含多个测试样例。
对于每个测试案例,输入为两个整数m和n(1<=m,n<=1000000)。
对应每个测试案例,输出m+n的值。
3 4 7 9
7 16
#include <iostream> #include "algorithm" using namespace std; int solutionAdd(int n,int m) { int num1 = 0, num2; do {//举例5+17,5(101),17(10001) num1 = n^m; //模拟二进制中各位相加(但不进位), 异或(不同则为真,结果为10100 num2 = (n & m) << 1;//获取模拟进位结果,因为只有相应位同时为1时才能为真,所以让结果往左移,结果00010 n = num1; m = num2; } while (num2 != 0);//如果还有进位,就再加上进位 return num1; } int main() { int n = 0, m = 0; while (cin >> n >> m) cout << solutionAdd(n,m) << endl; return 0; } /************************************************************** Problem: 1507 User: EbowTang Language: C++ Result: Accepted Time:50 ms Memory:1520 kb ****************************************************************/
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。
输入可能包含多个测试样例。
对于每个测试案例,输入为一个合法或者非法的字符串,代表一个整数n(1<= n<=10000000)。
对应每个测试案例,
若输入为一个合法的字符串(即代表一个整数),则输出这个整数。
若输入为一个非法的字符串,则输出“My God”。
分析:
本题考虑问题要尽可能全面
5 -5 +8
5 -5 8
#include "string" #include "algorithm" #include <iostream> #include <cstdio> using namespace std; int main() { string str; while (cin>>str) { bool sig = true, con = true; int ans = 0; if (str[0]=='-') { sig = false; } else if (str[0] == '+') { } else if (str[0] <= '9' && str[0] >='0') { ans = ans * 10; ans = ans + str[0] - '0'; } else//其他任何情况都是错误的 { con = false; } int i = 1; if (con) { while (i < str.size()) { if (str[i] >= '0' && str[i] <= '9') { ans = ans * 10; ans+=str[i++] - '0'; } else {//在第二个字符及其后面发现异常 con = false; break; } } } if (con)//要么输出异常,要么输出答案 { if (!sig) ans = -1 * ans; cout << ans << endl; } else { cout << "My God" << endl; } } return 0; } /************************************************************** Problem: 1508 User: EbowTang Language: C++ Result: Accepted Time:50 ms Memory:1520 kb ****************************************************************/
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
每个输入文件仅包含一组测试样例。
对于每组测试案例,输入一行代表要处理的字符串。
对应每个测试案例,出经过处理后的字符串。
We Are Happy
We%20Are%20Happy
#include "string" #include <iostream> using namespace std; int main() { string str; while (getline(cin,str)) { string sub("%20"); for (int i = 0; i < str.size(); i++) { if (str[i]==' ') str.replace(i,1,sub);//从字符串str第i个位置起,及其后面k(这里是1)个字符串替换为sub } cout << str << endl; } return 0; } /************************************************************** Problem: 1510 User: EbowTang Language: C++ Result: Accepted Time:890 ms Memory:2284 kb ****************************************************************/
用两个栈来实现一个队列,完成队列的Push和Pop操作。
队列中的元素为int类型。
每个输入文件包含一个测试样例。
对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数。
接下来的n行,每行输入一个队列操作:
1. PUSH X 向队列中push一个整数x(x>=0)
2. POP 从队列中pop一个数。
对应每个测试案例,打印所有pop操作中从队列pop中的数字。如果执行pop操作时,队列为空,则打印-1。
3 PUSH 10 POP POP
10 -1
#include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; class QueueByStack { public: QueueByStack(){}; ~QueueByStack(){}; void push(int n); void pop(); private: stack<int> s1;//辅助栈 stack<int> s2;//执行栈 }; void QueueByStack::push(int n) { if (s2.empty())//直接压栈即可 { s2.push(n); } else { while (!s2.empty())//依次弹出给栈s1,并使s2为空 { int num = s2.top(); s2.pop();//删除栈顶值 s1.push(num); } s2.push(n);//空的s2获得新数n while (!s1.empty())//依次弹出给栈s2,并使s1为空 { int num = s1.top(); s1.pop(); s2.push(num); } } } void QueueByStack::pop() { if (s2.empty()) { cout << -1 << endl; } else { cout << s2.top() << endl; s2.pop();//删除栈顶值 } } int main() { int n = 0; while (cin >> n) { cin.get();//换新行准备让str接收字符,如果没有将错误,找了好久才发现,他妈的 QueueByStack qs; string str; int num = 0; for (int i = 0; i < n; i++) { cin >> str; if (str == "POP") { qs.pop(); } else { cin >> num; qs.push(num); } } } return 0; } /************************************************************** Problem: 1512 User: EbowTang Language: C++ Result: Time Limit Exceed ****************************************************************/
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
输入可能包含多个测试样例。
对于每个输入文件,第一行输入一个整数T,代表测试样例的数量。对于每个测试样例输入为一个整数。
。n保证是int范围内的一个整数。
对应每个测试案例,
输出一个整数,代表输入的那个数中1的个数。
3 4 5 -1
1 2 32
#include <stdio.h> int Count (int n){ int cnt = 0; while (n){ ++cnt; n &= (n - 1); } return cnt; } int main(void){ int T; int n; while (scanf ("%d", &T) != EOF){ while (T-- != 0){ scanf ("%d", &n); printf ("%d\n", Count (n)); } } return 0; } /************************************************************** Problem: 1513 User: EbowTang Language: C++ Result: Accepted Time:90 ms Memory:1020 kb ****************************************************************/
给定一个数字N,打印从1到最大的N位数。
每个输入文件仅包含一组测试样例。
对于每个测试案例,输入一个数字N(1<=N<=5)。
对应每个测试案例,依次打印从1到最大的N位数。
1
1 2 3 4 5 6 7 8 9
#include "iostream" #include "stdio.h" #include "vector" #include "algorithm" using namespace std; int getMaxBitNum(int N) { int res = 0; for (size_t i = 0; i < N; i++) { res = res * 10; res = res + 9; } return res; } int main() { int N = 0; while (cin >> N) { if (N > 5 || N < 1) break; for (size_t i = 1; i <= getMaxBitNum(N); i++) printf("%d\n", i); } return 0; } /************************************************************** Problem: 1515 User: EbowTang Language: C++ Result: Accepted Time:50 ms Memory:1520 kb ****************************************************************/