首页 > 代码库 > 从零单排PAT1019,1020,1021,1022
从零单排PAT1019,1020,1021,1022
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 = 1089 9810 - 0189 = 9621 9621 - 1269 = 8352 8532 - 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 20 18 15 10 75 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:2 1:3 3: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; } }