1:多项式加法
- 总时间限制:
- 1000ms
- 内存限制:
- 5000kB
- 描述
-
我们经常遇到两多项式相加的情况,在这里,我们就需要用程序来模拟实现把两个多项式相加到一起。首先,我们会有两个多项式,每个多项式是独立的一行,每个多项式由系数、幂数这样的多个整数对来表示。
如多项式2x20- x17+ 5x9- 7x7+ 16x5+ 10x4 + 22x2- 15
对应的表达式为:2 20 -1 17 5 9 - 7 7 16 5 10 4 22 2 -15 0。
为了标记每行多项式的结束,在表达式后面加上了一个幂数为负数的整数对。
同时输入表达式的幂数大小顺序是随机的。
我们需要做的就是把所给的两个多项式加起来。
- 输入
- 输入包括多行。
第一行整数n,表示有多少组的多项式需要求和。(1 < n < 100)
下面为2n行整数,每一行都是一个多项式的表达式。表示n组需要相加的多项式。
每行长度小于300。 - 输出
- 输出包括n行,每行为1组多项式相加的结果。
在每一行的输出结果中,多项式的每一项用“[x y]”形式的字符串表示,x是该项的系数、y 是该项的幂数。要求按照每一项的幂从高到低排列,即先输出幂数高的项、再输出幂数低的项。
系数为零的项不要输出。 - 样例输入
-
2 -1 17 2 20 5 9 -7 7 10 4 22 2 -15 0 16 5 0 -1 2 19 7 7 3 17 4 4 15 10 -10 5 13 2 -7 0 8 -8 -1 17 2 23 22 2 6 8 -4 7 -18 0 1 5 21 4 0 -1 12 7 -7 5 3 17 23 4 15 10 -10 5 13 5 2 19 9 -7
- 样例输出
-
[ 2 20 ] [ 2 19 ] [ 2 17 ] [ 15 10 ] [ 5 9 ] [ 6 5 ] [ 14 4 ] [ 35 2 ] [ -22 0 ] [ 2 23 ] [ 2 19 ] [ 2 17 ] [ 15 10 ] [ 6 8 ] [ 8 7 ] [ -3 5 ] [ 44 4 ] [ 22 2 ] [ -18 0 ]
1 #include <iostream> 2 #include <map> 3 using namespace std; 4 template <class T> 5 struct MyMore{ 6 bool operator()(const T & a, const T & b) const{ 7 return a>b; 8 }//注意!!!函数后加const!!! 9 }; 10 typedef map<long int, long int, MyMore<int>> MyPoly;//按指数从大到小排序 11 int main(){ 12 int n, x, y, flag; 13 cin >> n; 14 while(n--){ 15 flag = 0;//记录输入的y为负数的次数 16 MyPoly p; 17 while(flag < 2){ 18 cin >> x >> y; 19 if(y >= 0) 20 p[y] += x; 21 //访问key=y的元素并加上系数,如果不存在,则新创建一个key为y、val为0的元素 22 else 23 ++flag; 24 } 25 MyPoly::iterator it; 26 for(it = p.begin(); it != p.end(); ++it){//从前到后遍历并输出 27 if(it->second)//输出系数非零项 28 cout << "[ " << it->second << " " << it->first << " ] "; 29 } 30 cout << endl; 31 } 32 return 0; 33 }
用这道题复习了map、multimap、set、multiset~
2:放苹果
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
- 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
- 输入
- 第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
- 输出
- 对输入的每组数据M和N,用一行输出相应的K。
- 样例输入
-
1 7 3
- 样例输出
-
8
- 方法一:递归
1 #include <iostream> 2 using namespace std; 3 int PutApple(int m, int n){//把m个苹果放在n个盘子里 4 if(m <= 1) return 1;//0或1个苹果 5 if(n == 1) return 1;//1个盘子 6 if(m >= n)//苹果不比盘子少,有空盘+无空盘的情况 7 return PutApple(m-n, n) + PutApple(m, n-1); 8 else//苹果比盘子少,必有空盘 9 return PutApple(m, n-1); 10 } 11 int main(){ 12 int t, m, n; 13 cin >> t; 14 while(t--){ 15 cin >> m >> n; 16 cout << PutApple(m,n) << endl; 17 } 18 return 0; 19 }
方法二:递推/动态规划
1 #include <iostream> 2 using namespace std; 3 int main(){ 4 int t, m, n, a[11][11]; 5 for(int j=0; j<=10; ++j)//0或1个苹果 6 a[0][j] = a[1][j] = 1; 7 for(int i=0; i<=10; ++i)//1个盘子 8 a[i][1] = 1; 9 for(int i=2; i<=10; ++i)//苹果数量 10 for(int j=2; j<=10; ++j){//盘子数量 11 if(i>=j)//苹果不少于盘子,可以y分为有空盘子和无空盘子两种情况 12 a[i][j] = a[i][j-1] + a[i-j][j]; 13 else//苹果比盘子少,必有空盘子 14 a[i][j] = a[i][j-1]; 15 } 16 cin >> t; 17 while(t--){ 18 cin >> m >> n; 19 cout << a[m][n] << endl; 20 } 21 return 0; 22 }
3:位查询
- 总时间限制:
- 5000ms
- 内存限制:
- 65536kB
- 描述
-
给出N个范围在[0, 65535]的整数,编程支持以下的操作:
(1)修改操作:C d,所有的数都增加d。如果超过65535,把结果模65536。 0 <= d <= 65535
(2)查询操作:Q i,统计在N个正整数中有多少个整数其对应的二进制形式的第i位二进制位为非0。0 <= i <= 15。并且最低位i为0。
最后,输出所有查询操作的统计值。 - 输入
- 输入的第一行为两个正整数N,M,其中N为操作的整数的个数,而M为具体有多少个操作。
输入的第二行为N个正整数,为进行操作的N个正整数。
下面有M行,分别表示M个操作。
N<=100000,M<=200000 - 输出
- 输出所有查询操作Q的统计值,每一个查询操作统计结果输出为一行。
- 样例输入
-
3 5 1 2 4 Q 1 Q 2 C 1 Q 1 Q 2
- 样例输出
-
1 1 2 1
1 #include <iostream> 2 using namespace std; 3 //num中的N个数字加d 4 void Corr(int num[], int d, int N){ 5 for(int i=0; i<N; ++i){ 6 num[i] += d; 7 if(num[i] > 65535) 8 num[i] %= 65535; 9 } 10 } 11 //num中的N个数字进行二进制判断 12 int Ques(int num[], int d, int N){ 13 int cnt = 0; 14 for(int i=0; i<N; ++i) 15 //第d位为1 且 低d位为0 16 if( (num[i] & (1<<d)) && !(num[i] & ((1<<d) - 1)) ) 17 ++cnt; 18 return cnt; 19 } 20 int main(){ 21 char cmd; 22 int N, M, num[100010], d; 23 cin >> N >> M; 24 for(int i=0; i<N; ++i)//输入数字 25 cin >> num[i]; 26 while(M--){//输入指令并判断 27 cin >> cmd >> d; 28 if(cmd == 'C') 29 Corr(num, d, N); 30 else 31 cout << Ques(num, d, N) << endl; 32 } 33 return 0; 34 }
4:大整数乘法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个不超过200位的非负整数的积。
- 输入
- 有两行,每行是一个不超过200位的非负整数,没有多余的前导0。
- 输出
- 一行,即相乘后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
- 样例输入
-
12345678900 98765432100
- 样例输出
-
1219326311126352690000
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 int main(){ 5 int a[250]={0}, b[250]={0}, c[500]={0}, la,lb; 6 string na, nb; 7 //输入并倒序储存a和b 8 cin >> na >> nb; 9 la = (int)na.length(); 10 lb = (int)nb.length(); 11 for(int i=0; i<la; ++i) 12 a[i] = na[la-i-1] - '0'; 13 for(int i=0; i<lb; ++i) 14 b[i] = nb[lb-i-1] -'0'; 15 for(int i=0; i<la; ++i)//a的从低到高第i位 16 for(int j=0; j<lb; ++j)//b的从低到高第j位 17 c[i+j] += a[i] * b[j]; 18 for(int i=0; i<la+lb; ++i){//进位 19 c[i+1] += c[i] / 10; 20 c[i] %= 10; 21 } 22 int rest = c[la+lb]/10, lc = la+lb; 23 while(rest){//进位 24 c[lc] %= 10; 25 c[++lc] = rest; 26 rest = c[lc]/10; 27 } 28 for(; c[lc]==0 && lc; --lc);//找到最高的非零位 29 for(int i=lc; i>=0; --i) 30 cout << c[i]; 31 return 0; 32 }