1. 知识点总结
待解决:1060第六个测试点
得分:75+/100
知识点总结:树状数组、栈、数学、暴力、科学计数法
题目 | 难度 | 知识点 |
---|---|---|
1057 Stack | 🎯🎯🎯😅 | 树状数组 |
1058 A+B in Hogwarts | 🎯 | 数学 |
1059 Prime Factors | 🎯🎯 | 暴力 |
1060 Are They Equal | 🎯🎯😅 | 科学计数法 |
2. 分题题解
2.1 1057 Stack
一开始是暴力写的……哇可想而知的惨淡捏
所以一个栈st
来表示栈,再用树状数组存val
所在位置(利用getsum
)求
因为题干中说key
的值小于100000,所以可以利用树状数组c
去记录信息,也就是getsum(x)
求的是值x
在形成的数组中的下标
#include<bits/stdc++.h>
#define lowbit(i) ((i)&(-i))
using namespace std;
string str;
int N;
int val;
stack<int>st;
const int maxn=1e5+1;
//树状数组数据结构以及对应的函数
int c[maxn];
void update(int x,int v){
//在x-最后区间内更新
for(int i=x;i<maxn;i+=lowbit(i)){
c[i]+=v;
}
}
int getsum(int x){
int sum=0;
for(int i=x;i>=1;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void PeekMedian(){
int left=1,right=maxn,mid,k=(st.size()+1)/2;
while(left<right){
mid=(left+right)/2;
if(getsum(mid)>=k){
right=mid;
}else{
left=mid+1;
}
}
printf("%d\n",left);
}
int main(){
scanf("%d",&N);
getchar();
while(N--){
getline(cin,str);
if(str[1]=='o'){
//POP
if(st.empty()){
printf("Invalid\n");
}else{
val=st.top();
printf("%d\n",val);
update(val,-1);
st.pop();
}
}else if(str[1]=='e'){
//PEEKMEDIAN
if(st.empty()){
printf("Invalid\n");
}else{
PeekMedian();
}
}else{
//PUSH
sscanf(str.c_str(),"Push %d",&val);
st.push(val);
update(val,1);
}
}
return 0;
}
2.2 1058 A+B in Hogwarts
简单的自定义加法进位运算
#include<bits/stdc++.h>
using namespace std;
struct Num{
int a,b,c;//[0,1e7] [0,17] [0,29]
};
Num A,B,C;
int main(){
scanf("%d.%d.%d %d.%d.%d",&A.a,&A.b,&A.c,&B.a,&B.b,&B.c);
//printf("%d.%d.%d %d.%d.%d\n",A.a,A.b,A.c,B.a,B.b,B.c);
C.c=(A.c+B.c)%29;
C.b=(A.b+B.b+(A.c+B.c)/29)%17;
C.a=((A.a+B.a)+(A.b+B.b+(A.c+B.c)/29)/17);
printf("%d.%d.%d",C.a,C.b,C.c);
return 0;
}
2.3 1059 Prime Factors
暴力求取Prime公因数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num;
bool isPrime(ll x){
if(x==2||x==3||x==5||x==7){
return true;
}
for(int i=2;i*i<=x;i++){
if(x%i==0){
return false;
}
}
return true;
}
struct Node{
ll num;
int ep;
};
vector<Node>nodes;
Node temp;
int main(){
scanf("%lld",&num);
ll fac=num;
ll a=2;
if(num==1){
printf("1=1");
return 0;
}
while(num){
if(num%a==0&&isPrime(a)){
temp.ep=0;
temp.num=a;
while(num%a==0&&num!=0){
num/=a;
temp.ep++;
}
//printf("----%lld %d\n",temp.num,temp.ep);
nodes.push_back(temp);
}else{
if(isPrime(num)){
if(num==1)break;
temp.num=num;
temp.ep=1;
nodes.push_back(temp);
break;
}
}
a++;
}
printf("%lld=",fac);
for(int i=0;i<nodes.size();i++){
if(i){
printf("*");
}
if(nodes[i].ep>1){
printf("%lld^%d",nodes[i].num,nodes[i].ep);
}else{
printf("%lld",nodes[i].num);
}
}
return 0;
}
2.4 1060 Are They Equal
这题卡在第六个测试点,目前还没有整明白是哪里的问题,需要回炉
#include<bits/stdc++.h>
using namespace std;
//字符串处理的问题
int N;
string A,B,aa,bb;//11.1 3
string Convert(string a){
if(N==0){
return "0.0*10^0";
}
string ans;
if(a=="0"){
ans="0*10^0";
return ans;
}
ans="0.";
int pos=0;
int len=a.length();
for(;pos<len;pos++){
if(a[pos]=='.'){
break;
}
}
bool flag=false;
int cnt=0;
int first_num_pos=-1;
for(int i=0;i<len;i++){
if(a[i]<='9'&&a[i]>='1'){
if(flag==false){
flag=true;
first_num_pos=i;
}
ans+=a[i];
cnt++;
}else if(flag&&a[i]=='0'){
ans+=a[i];
cnt++;
}
if(cnt==N){
break;
}
}
while(cnt<N){
ans+='0';
cnt++;
}
if(first_num_pos==-1){
return ans+="*10^0";
}
if(pos-first_num_pos<0){
int k=first_num_pos-pos-1;
if(k){
ans+="*10^-";
string temp="";
while(k){
temp+=k%10+'0';
k/=10;
}
reverse(temp.begin(),temp.end());
ans+=temp;
}else{
ans+="*10^0";
}
}else{
int k=pos-first_num_pos;
if(k){
ans+="*10^";
string temp="";
while(k){
temp+=k%10+'0';
k/=10;
}
reverse(temp.begin(),temp.end());
ans+=temp;
}else{
ans+="*10^0";
}
}
return ans;
}
int main(){
cin>>N>>A>>B;
aa=Convert(A);
bb=Convert(B);
if(aa==bb){
printf("YES %s",aa.c_str());
}else{
printf("NO %s %s",aa.c_str(),bb.c_str());
}
return 0;
}
3. 参考资料
1057. Stack (30)-PAT甲级真题(树状数组)_柳婼的博客-CSDN博客
PAT 1060 Are They Equal (25 分)(关于测试点4与6错误) 极端测试样例 燚_罗正燚的博客-CSDN博客