最近准备考pat甲级,今天先找了去年的题目练了练。
总结:
(1)时间分配的不够合理,这次我用了15min读完了所有题,感觉不难就依次去做了,后来第二题卡了太久了,
就导致后面两题的时间不够了,最后两题没拿满分(后来补题时发现好简单QAQ),下次如果25分的题时间超过40min就应该
先看后面的。
(2)做题速度还是很慢,有时候思路都是有的,却要磨蹭好久,一定要改掉这个坏习惯。
pat-1152(hash)
思路:
用hash处理整个字符串,然后依次访问[i,i+k-1]区间的数字,判断是否为素数即可。
注意:
(1)hash数组是unsigned int类型的,不要写成 unsigned long long类型的,不然素数一判断就爆。
(2)从进行hash时要从[0,L-K]区间,考虑第一字母。
pat-1153(排序模拟)
题意:
三种要求输出
1、输出一个区块的所有排好序的卡号和成绩,卡号升序,成绩降序;
2、输出所有考场的考试人数,和这个考场内的考生成绩总和;
3、输出某一天的考场和考场内的考试人数,考场序号升序,人数降序。
思路:
排序,按照要求排序,还有stl的使用。
注意:
(1)这道题我WA了好久,开始我想直接全部排序完再直接输出,不然会超时,但是后来发现条件1,2容易满足,
条件3不容易,看列别人的文章,我发现可以现用现排(不管超不超时,先模拟出来再说)。
(2)三个条件都要考虑不存在的条件,一开始我第一就忘记考虑了。
(3)注意输出的格式,日期要是06d,6个单位。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 100100;
struct Node{
int score,date,sit_id,id,level;
char ss[50];
}cur[maxn];
int sit_n[maxn],sit_s[maxn],vis[maxn];
struct NN{
int id,num;
};
vector <NN> vc;
bool tmp(NN a,NN b)
{
if(a.num!=b.num) return a.num>b.num;
else return a.id<b.id;
}
bool cmp(Node a,Node b)
{
if(a.level!=b.level) return a.level>b.level;
else{
if(a.score!=b.score) return a.score>b.score;
else{
if(strcmp(a.ss,b.ss)!=0) return strcmp(a.ss,b.ss)<0;
}
}
}
int MIN(int x,int y)
{
return x<y?x:y;
}
int main(void)
{
int n,m,i,j,x,y,tp,ty;
char str[50];
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s %d",str,&x);
cur[i].score=x;
if(str[0]=='T') cur[i].level=1;
else if(str[0]=='A') cur[i].level=2;
else if(str[0]=='B') cur[i].level=3;
for(cur[i].sit_id=0,j=1;j<=3;j++) cur[i].sit_id=cur[i].sit_id*10+(str[j]-'0');
for(cur[i].date=0,j=4;j<=9;j++) cur[i].date=cur[i].date*10+(str[j]-'0');
for(cur[i].id=0,j=10;j<=12;j++) cur[i].id=cur[i].id*10+(str[j]-'0');
sit_n[cur[i].sit_id]++;sit_s[cur[i].sit_id]+=cur[i].score;
strcpy(cur[i].ss,str);
}
sort(cur+1,cur+1+n,cmp);
int TT=n+1,AA=n+1,BB=n+1;
for(i=1;i<=n;i++){
if(cur[i].level==1) TT=MIN(TT,i);
else if(cur[i].level==2) AA=MIN(AA,i);
else if(cur[i].level==3) BB=MIN(BB,i);
}
for(j=1;j<=m;j++){
scanf("%d",&ty);
printf("Case %d: %d ",j,ty);
if(ty==1){
scanf("%s",str);
printf("%s\n",str);
if(str[0]=='T'){
if(TT!=n+1)
for(i=TT;cur[i].level==1;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
else printf("NA\n");
}
else if(str[0]=='A'){
if(AA!=n+1)
for(i=AA;cur[i].level==2;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
else printf("NA\n");
}
else if(str[0]=='B'){
if(BB!=n+1)
for(i=BB;cur[i].level==3;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
else printf("NA\n");
}
else printf("NA\n");
}
else if(ty==2){
scanf("%d",&x);
printf("%d\n",x);
if(sit_n[x]!=0) printf("%d %d\n",sit_n[x],sit_s[x]);
else printf("NA\n");
}
else{
scanf("%d",&x);
printf("%06d\n",x);
memset(vis,0,sizeof(vis));
vc.clear();
NN opp;
int ft=0;
for(i=1;i<=n;i++)
if(cur[i].date==x) vis[cur[i].sit_id]++,ft=1;
/*if(ft=0){
printf("NA\n");
continue;
}*/
for(i=1;i<=n;i++)
if(vis[cur[i].sit_id]!=0){
opp.id=cur[i].sit_id;
opp.num=vis[cur[i].sit_id];
vc.push_back(opp);
vis[cur[i].sit_id]=0;
}
if(vc.size()!=0){
sort(vc.begin(),vc.end(),tmp);
for(i=0;i<vc.size();i++) printf("%03d %d\n",vc[i].id,vc[i].num);
}
else printf("NA\n");
}
}
return 0;
}
pat-1154(送分题)
思路:就是判断一下一条边的两个点颜色是否相同。
pat-1155(二叉树的遍历+堆)
思路:
二叉堆就是一个完全二叉树,可以用中序遍历判断是最大堆还是最小堆,
完全二叉树性质:最多2^x-1个节点,最少2^(x-1)-1个节点,所以求出最少的节点个数m,
所以m就是最右边的节点,然后依次从叶子节点比遍历就好了。
(感觉25和30分的题目出反了)。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 100100;
int tree[maxn],f1,f2,vis[maxn];
vector <int> vc[maxn];
void In1(int x)
{
if(tree[x]){
In1(x*2);
if(tree[x*2]&&tree[x*2]<tree[x]) f1=0;
if(tree[x*2+1]&&tree[x*2+1]<tree[x]) f1=0;
if(tree[x*2]+tree[x*2+1]==0) vis[x]=1;
In1(x*2+1);
}
}
void In2(int x)
{
if(tree[x]){
In2(x*2);
if(tree[x*2]&&tree[x*2]>tree[x]) f2=0;
if(tree[x*2+1]&&tree[x*2+1]>tree[x]) f2=0;
if(tree[x*2]+tree[x*2+1]==0) vis[x]=1;
In2(x*2+1);
}
}
int main(void)
{
int n,i,j,m=1,N=2;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&tree[i]);
while(N<=n){
N*=2;m*=2;
}
f1=f2=1;
In1(1);In2(1);
for(i=1;i<=n;i++)
if(vis[i]==1){
for(j=i;j>0;j/=2) vc[i].push_back(tree[j]);
}
m--;
for(i=m;i>=1;i--)
if(vis[i]==1){
int tp=vc[i].size();
for(j=tp-1;j>=0;j--){
if(j!=tp-1) printf(" ");
printf("%d",vc[i][j]);
}
printf("\n");
}
for(i=n;i>=m+1;i--)
if(vis[i]==1){
int tp=vc[i].size();
for(j=tp-1;j>=0;j--){
if(j!=tp-1) printf(" ");
printf("%d",vc[i][j]);
}
printf("\n");
}
if(f1) printf("Min Heap\n");
else if(f2) printf("Max Heap\n");
else printf("Not Heap\n");
return 0;
}