从零单排PAT1019,1020,1021,1022

来源:互联网 发布:怎么在淘宝注册品牌 编辑:程序博客网 时间:2024/05/22 04:50


1019数字黑洞  题目要求:

给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。

例如,我们从6767开始,将得到

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...

现给定任意4位正整数,请编写程序演示到达黑洞的过程。

输入格式:

输入给出一个(0, 10000)区间内的正整数N。

输出格式:

如果N的4位数字全相等,则在一行内输出“N - N = 0000”;否则将计算的每一步在一行内输出,直到6174作为差出现,输出格式见样例。注意每个数字按4位数格式输出。

输入样例1:
6767
输出样例1:
7766 - 6677 = 10899810 - 0189 = 96219621 - 1269 = 83528532 - 2358 = 6174
输入样例2:
2222
输出样例2:
2222 - 2222 = 0000
解题思路:就是一个简单的排序,我是以字符串的形式存储,然后将数字从大到小,从小到大排列,并计算得出对应的数值,最后相减就可以计算,由于题目已经是4位数,所以可以直接分配数据空间,但是需要注意的一个case是如果计算的结果不是四位数那该怎么办?排序还是一样的,注意直接输出字符串,不要输出数字(可能会出现三位数);如果所有数字相同,输出0000


源代码:

#include <iostream>#include <algorithm>using namespace std;int compareS(const void *a,const void *b){return *(int*)a > *(int*)b;  //升序排列}int compareJ(const void *a,const void *b){return *(int*)a < *(int*)b;  //降序排列}int getNumber(int a){int d = a;int b = 0;int c[4] = {0,0,0,0}; //存储第一个数字int e[4] = {0,0,0,0}; //存储第二个数字int result = 0;for(int i=0;i<4;i++){c[i] = d % 10;e[i] = d % 10;d = d/10;}qsort(&c[0],4,sizeof(int),compareJ);qsort(&e[0],4,sizeof(int),compareS);a = 0;for(int i=0;i<4;i++){a = a*10 + c[i];  //得到实际数字b = b*10 + e[i];}result = a - b;if(result != 0 && result >= 1000){cout << a << " " << "-" << " " << c[3] << c[2] << c[1] << c[0] << " " << "=" << " " << result << endl;}else if(result == 0){cout << a << " " << "-" << " " << c[3] << c[2] << c[1] << c[0] << " " << "=" << " " << "0000" << endl;}else //只会出现3位数,不可能出现小于3位数{cout << a << " " << "-" << " " << c[3] << c[2] << c[1] << c[0] << " " << "=" << " " << '0' << result << endl;}return result;}int main(){int num;cin >> num;do//必须要执行第一个计算{num = getNumber(num);}while( num != 6174 && num != 0);system("pause");return 0;}

1020月饼  题目要求:

月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。

注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18、15、10万吨,总售价分别为75、72、45亿元。如果市场的最大需求量只有20万吨,那么我们最大收益策略应该是卖出全部15万吨第2种月饼、以及5万吨第3种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入格式:

每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数、以及不超过500(以万吨为单位)的正整数D表示市场最大需求量。随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。

输出格式:

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后2位。

输入样例:
3 2018 15 1075 72 45
输出样例:
94.50

解题思路:这其实就是一个简单的贪婪算法,先根据单价最高的进行计算,如果单价最高的总量不能满足,则用单价第二高的,以此类推,直到达到市场最大需求量。因为一直有几个case过不去,后来看看别人的代码,是因为自己的对于总量和单价都用int型表示,在这里不够准确,索性都用float类型,也省去了强类型转换的问题。还有一个是,cout的标准输出,输出小数点后两位,用cout.setf(ios::fixed); 


源代码:

#include <iostream>#include <vector>#include <algorithm>#include <iomanip> using namespace std;void swap (int *a,int *b){int temp = *a;*a = *b;*b = temp;}void swap(float *a,float *b) //重载{float temp = *a;*a = *b;*b = temp;}int main(){int N,max;//不同的个数,最大吨数cin >> N >> max;vector<float> kucun;//库存数量vector<float> zongjia;//各个总价vector<float> per;for(int i=0;i<N;i++){float temp ;cin >> temp;kucun.push_back(temp);}for(int i=0;i<N;i++){float temp ;cin >> temp;zongjia.push_back(temp);per.push_back((float)temp/kucun[i]);}for(int i=0;i<N-1;i++) //冒泡排序{for(int j=0;j<N-1;j++){if(per[j]<per[j+1])  //数组降序排列{swap(per[j],per[j+1]);swap(kucun[j],kucun[j+1]);swap(zongjia[j],zongjia[j+1]);}}}int residue = max;//剩余吨数float income = 0; //实际收益int temp;int count;for(count=0;count<N;count++){temp = residue - kucun[count];if(temp < 0){income += residue * per[count];  //得到总收益break;}else{residue = temp;//income += kucun[i] * per[i];  //得到总收益income += zongjia[count];}}cout.setf(ios::fixed); cout << setprecision(2) << income ;system("pause");return 0;}





1021个位数统计  题目要求:

给定一个k位整数N = dk-1*10k-1 + ... + d1*101 + d0 (0<=di<=9, i=0,...,k-1, dk-1>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定N = 100311,则有2个0,3个1,和1个3。

输入格式:

每个输入包含1个测试用例,即一个不超过1000位的正整数N。

输出格式:

对N中每一种不同的个位数字,以D:M的格式在一行中输出该位数字D及其在N中出现的次数M。要求按D的升序输出。

输入样例:
100311
输出样例:
0:21:33:1

解题思路:这是一道不能再简单的题目,所以没什么可说的


源代码:

#include <iostream>#include <string>using namespace std;int main(){string num;int a[10] = {0,0,0,0,0,0,0,0,0,0};//int a[10];//memset(a,0,sizeof(a));cin >> num;int lenth = num.size();for(int i=0;i<lenth;i++){switch(num[i]){case '0':a[0]++;break;case '1':a[1]++;break;case '2':a[2]++;break;case '3':a[3]++;break;case '4':a[4]++;break;case '5':a[5]++;break;case '6':a[6]++;break;case '7':a[7]++;break;case '8':a[8]++;break;case '9':a[9]++;break;}}for(int i=0;i<10;i++){if(a[i] != 0){cout << i << ":" << a[i] <<endl;}}system("pause");return 0;}



1022 D进制 A+B 题目要求:

输入两个非负10进制整数A和B(<=230-1),输出A+B的D (1 < D <= 10)进制数。

输入格式:

输入在一行中依次给出3个整数A、B和D。

输出格式:

输出A+B的D进制数。

输入样例:
123 456 8
输出样例:
1103

解题思路:这是计算机相关专业的基础知识,需要知道只是怎么计算D进制数,因为数都小于2的30次-1,所以可以用int型直接存储,相加得到的数据整除D,最后逆序输出即可得到D进制数(原本是先得到10进制数,但随后就发现,只要把10换成D,就可以得到D进制数),但需要注意的case是两个非负的整数相加可能为0,所以考虑0时,输出0。


源代码:

#include <iostream>#include <vector>using namespace std;int main(){unsigned int A,B,D;vector <int> a;  //存储10进制数vector <int> b;//存储N进制数cin >> A >> B >> D;unsigned int temp = A + B;if(temp == 0) //如果=0时,因为都是非0,这个条件要考虑{cout << '0' << endl;system("pause");return 0;}else{while(temp!=0){a.push_back(temp % D);temp /= D;}int lenth = a.size();for(int i=0;i<lenth;i++){cout << a[lenth - i - 1]; }cout << endl;system("pause");return 0;}}


0 0