1:多项式加法

总时间限制: 
1000ms
 
内存限制: 
5000kB
描述

    我们经常遇到两多项式相加的情况,在这里,我们就需要用程序来模拟实现把两个多项式相加到一起。首先,我们会有两个多项式,每个多项式是独立的一行,每个多项式由系数、幂数这样的多个整数对来表示。

如多项式2x20- x17+ 5x9- 7x7+ 16x5+ 10x+ 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 }
View Code

用这道题复习了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 }
View Code

方法二:递推/动态规划

 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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

posted on 2019-09-20 13:26  茵茵嘤  阅读(443)  评论(0编辑  收藏  举报