1090. 危险品装箱
题目分析:
这里有一个问题需要好好注意,从给的样例可以看到,可能一个物品与2种不同的物品都会配对成为危险品,所以这里比较好的策略是开一个比较大的数组,以下标表示物品编号,储存的值表示配对的危险品编号,例如:20005与20001是危险品,20006,20005构成危险品,则Arr[2005]=20001,Arr[20006]=20005。
源代码
#include <cstdio>
int main()
{
int unpairNum,listNum;
scanf("%d %d",&unpairNum,&listNum);
int *danList,*goodsList;
danList=new int [100000];
goodsList=new int[100000];
for(int i=0;i<100000;++i) danList[i]=goodsList[i]=0;
int dangeID1,dangeID2;
for(int i=0;i<unpairNum;++i){
scanf("%d %d",&dangeID1,&dangeID2);
if(danList[dangeID1]==0)
danList[dangeID1]=dangeID2;
else danList[dangeID2]=dangeID1;
}
bool Is_safe;
for(int i=0;i<listNum;++i){
int num;
scanf("%d",&num);
int *tmp=new int[num];
for(int i=0;i<num;++i){
scanf("%d",&tmp[i]);
goodsList[tmp[i]]=1;
}
Is_safe=true;
for(int i=0;i<num;++i)
if(danList[tmp[i]]&&goodsList[danList[tmp[i]]]){ //如果此物品出现在危险品列表且不相容物品也在清单中
Is_safe=false;
break;
}
if(Is_safe) printf("Yes\n");
else printf("No\n");
for(int i=0;i<num;++i)
goodsList[tmp[i]]=0; //重置回0
delete []tmp; //释放空间
}
delete []danList;
delete []goodsList;
return 0;
}
1091. N-自守数
题目分析:
这题比较容易,从1开始遍历,依次寻找如果满足要求那就立即输出。
源代码
#include <cstdio>
int main()
{
int num;
scanf("%d",&num);
while(num--){
int count=0; //统计数字位数
int value,copy;
scanf("%d",&value);
copy=value;
while(copy){
copy/=10;
count++;
}
bool find=false;
for(int i=1;i<10;++i){ //N最大9
int mul=value*value*i;
copy=value;
for(int j=0;j<count;++j){
if(mul%10!=copy%10) break;
mul/=10; copy/=10;
}
if(copy==0){ //说明末尾几位恰为K
find=true;
printf("%d %d\n",i,value*value*i);
break;
}
}
if(!find) printf("No\n");
}
return 0;
}
1092. 最好吃的月饼
题目分析:
根据输入依次累加求出各类月饼的总销量,然后遍历一遍找出销量最高值max,再遍历一遍,将所有销量为max的月饼编号输出即可。
源代码
#include <cstdio>
int main()
{
int kinds,cityNum,sell;
scanf("%d %d",&kinds,&cityNum);
int *sum=new int[kinds];
for(int i=0;i<kinds;++i)
sum[i]=0;
while(cityNum--){
for(int i=0;i<kinds;++i){
scanf("%d",&sell);
sum[i]+=sell;
}
}
int max=-1;
for(int i=0;i<kinds;++i)
if(max<sum[i]) max=sum[i];
printf("%d\n",max);
int first=0;
for(int i=0;i<kinds;++i)
if(sum[i]==max){
if(first) printf(" ");
first++;
printf("%d",i+1);
}
delete []sum;
return 0;
}
1093. 字符串A+B
题目分析:
首先用一个大小为128的int数组来记录各个字符是否出现,出现记为1,否则记为0。然后输出时,从第一个字符开始,查询下标为该字符对应的ASCII码的元素是否为1,为1则输出并将其修改为0,否则不输出,这样就可以保证所有相同字符出现且仅出现一次。
源代码
#include <iostream>
#include <string>
int main()
{
using namespace std;
int exist[128];
for(int i=0;i<128;++i) exist[i]=0;
string sA,sB;
getline(cin,sA);
getline(cin,sB);
int lenA=sA.size(),lenB=sB.size();
for(int i=0;i<lenA;++i)
exist[sA[i]]=1;
for(int i=0;i<lenB;++i)
exist[sB[i]]=1;
for(int i=0;i<lenA;++i)
if(exist[sA[i]]){
exist[sA[i]]=0;
putchar(sA[i]);
}
for(int i=0;i<lenB;++i)
if(exist[sB[i]]){
exist[sB[i]]=0;
putchar(sB[i]);
}
return 0;
}
1094. 谷歌的招聘
题目分析:
核心思想还是判定素数,不过这里需要将字符串转化成数字来进行计算,可以用stoi()这个函数,作用是将一个const string对象转化成对应的十进制数,也可以用atoi(),不过它的参数是const char*,如果是string对象的话需要用c_str()函数创建一个const char*再用atoi()。不过这两个函数可能在Dev C++5.10上使用不了,我测试过编译不了,但g++可以顺利编译运行。
源代码
/******注:这里用到的stoi()函数在Dev C++5.10版本中无法编译,VS2017中可以顺利编译*******/
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
bool isPrim(int num) {
if (num == 2 || num == 3) return true;
if (num % 6 == 1 || num % 6 == 5) {
int i, gap = 4, limit = sqrt((double)num);
for (i = 5; i <= limit; i += gap) {
if (num%i == 0) return false;
if (gap == 2) gap = 4;
else gap = 2;
}
return true;
}
return false;
}
int main()
{
using namespace std;
int len, key; //数字长度以及K
string number;
cin >> len >> key >> number;
bool findPrim = false;
for (int i = key - 1; i < len; ++i) {
int value;
string tmp = number.substr(i - key + 1, key);
value = stoi(tmp);
if (isPrim(value)) {
findPrim = true;
cout << tmp;
break;
}
}
if (!findPrim) printf("404");
return 0;
}
1095. 解码PAT准考证
题目分析:
真是让我痛苦非常的一道题,大概也是编写的最久的一道题,由于现在对STL不熟悉,写起来真的非常,非常麻烦,不过好在他是最后一道题,刷完这道就乙级通关了~
由于实在是比较长,很多细节,直接放上了代码,网上有一些写的很好的代码很简单,柳婼的博客上有一篇代码,47行很简洁,这里放上链接,大家还是移步去看看别人写的优秀代码来的好,希望自己也早日提升水平,写出简洁优美的代码。
https://blog.csdn.net/liuchuo/article/details/84972869
源代码
//2020.03.26
#include <cstdio>
#include <algorithm>
#include <cstring>
struct candiInfo{
char id[14]; //准考证号
int score;
};
struct testRoom{
int number=0; //考场人数
int id; //id
};
bool cmp1(const candiInfo& c1,const candiInfo& c2){ //按类型1排序
if(c1.id[0]!=c2.id[0]) return c1.id[0]<c2.id[0]; //按类型字母排序,依次A B T
if(c1.score!=c2.score) return c1.score>c2.score; //按分数非升序排列
return strcmp(c1.id,c2.id)<0; //按准考证字典升序输出
}
bool cmp2(const candiInfo& c1,const candiInfo& c2){ //按类型3排列
char date1[7],date2[7];
strncpy(date1,&c1.id[4],6); date1[6]='\0';
strncpy(date2,&c2.id[4],6); date2[6]='\0';
int compare=strcmp(date1,date2);
if(compare!=0) return compare<0; //按日期升序排列
int examRoom1,examRoom2;
examRoom1=(c1.id[1]-'0')*100+(c1.id[2]-'0')*10+c1.id[3]-'0';
examRoom2=(c2.id[1]-'0')*100+(c2.id[2]-'0')*10+c2.id[3]-'0';
return examRoom1<examRoom2; //按考场升序排列
}
bool cmp3(const testRoom&t1,const testRoom& t2){
if(t1.number!=t2.number) return t1.number>t2.number;
return t1.id<t2.id;
}
int main()
{
int candiNum,quryNum;
scanf("%d %d",&candiNum,&quryNum);
candiInfo* candiList1=new candiInfo[candiNum];
candiInfo* candiList2=new candiInfo [candiNum];
int room[1000][2]={0};
for(int i=0;i<candiNum;++i){
scanf("%s %d",candiList1[i].id,&candiList1[i].score);
candiList2[i]=candiList1[i];
int examroom=(candiList1[i].id[1]-'0')*100+(candiList1[i].id[2]-'0')*10+candiList1[i].id[3]-'0';
room[examroom][0]++; //人数+1;
room[examroom][1]+=candiList1[i].score; //计算该考场总分
}
std::sort(candiList1,candiList1+candiNum,cmp1);
std::sort(candiList2,candiList2+candiNum,cmp2);
int caseID;
int order=0;
while(quryNum--){
order++;
scanf("%d",&caseID);
getchar(); //读取空格
switch(caseID){
case 1:{
char type=getchar();
int j;
for(j=0;j<candiNum&&candiList1[j].id[0]!=type;++j); //找到符合要求可输出的位置
printf("Case %d: 1 %c\n",order,type);
if(j==candiNum) {printf("NA\n");break; }
while(j<candiNum&&candiList1[j].id[0]==type) {
printf("%s %d\n",candiList1[j].id,candiList1[j].score);
j++;
}
break;
}
case 2:{
int roomid;
scanf("%d",&roomid);
printf("Case %d: 2 %d\n",order,roomid);
if(room[roomid][0]==0) {printf("NA\n");break;}
printf("%d %d\n",room[roomid][0],room[roomid][1]);
break;
}
case 3:{
char date[7];
char tmp[7];
tmp[6]='\0';
scanf("%s",date);
int begin=-1,end;
for(int j=0;j<candiNum;++j){
strncpy(tmp,&candiList2[j].id[4],6);
if(strcmp(tmp,date)==0){
if(begin<0) begin=j;
end=j;
}
}
int count=1; //统计有几个不同考场
printf("Case %d: 3 %s\n",order,date);
if(begin<0) {printf("NA\n");break;}
int pre=(candiList2[begin].id[1]-'0')*100+(candiList2[begin].id[2]-'0')*10+candiList2[begin].id[3]-'0';
int cur;
for(int i=begin+1;i<=end;++i){
cur=(candiList2[i].id[1]-'0')*100+(candiList2[i].id[2]-'0')*10+candiList2[i].id[3]-'0';
if(cur!=pre){ pre=cur;count++;}
}
testRoom *show=new testRoom[count];
pre=pre=(candiList2[begin].id[1]-'0')*100+(candiList2[begin].id[2]-'0')*10+candiList2[begin].id[3]-'0';
int temp=0;
show[temp].id=pre;
show[temp].number++;
for(int i=begin+1;i<=end;++i){
cur=(candiList2[i].id[1]-'0')*100+(candiList2[i].id[2]-'0')*10+candiList2[i].id[3]-'0';
if(cur!=pre){
show[++temp].id=cur;
show[temp].number++;
pre=cur;
}
else show[temp].number++;
}
std::sort(show,show+count,cmp3);
for(int i=0;i<count;++i)
printf("%d %d\n",show[i].id,show[i].number);
delete []show;
break;
}
default: break;
}
}
delete []candiList1;
delete []candiList2;
return 0;
}
写到这里,历时将近一个月,我的PAT乙级95道题终于全部刷完了,见识到了别人的代码与自己代码的差距,也学到了不少东西。也很高兴自己能按自己的想法和计划把它做下来,也祝愿未来的自己以及所有奋战苦练的人,都能够坚持自己的初心,一步一步地把自己的目标实现下来。乙级也还只是一个开始,甲级要继续冲了嗷!