PAT B1032 挖掘机技术哪家强
#include<stdio.h> #include<string.h> int main() { int school[100005]; int n,schoolnum,score; scanf("%d",&n); memset(school,0,sizeof(school)); int maxscore=0; int maxschool=1; for(int i=1;i<=n;i++) { scanf("%d%d",&schoolnum,&score); school[schoolnum]+=score; if(school[schoolnum]>maxscore) { maxschool=schoolnum; maxscore=school[schoolnum]; } } printf("%d %d",maxschool,maxscore); return 0; }
PAT B1036 跟奥巴马一起编程
#include<stdio.h> int main() { int num; char c; scanf("%d %c",&num,&c); int row=num/2+num%2; for(int i=1;i<=row;i++) { if(i==1||i==row) { for(int j=1;j<=num;j++) printf("%c",c); } else { printf("%c",c); for(int j=2;j<=num-1;j++) printf(" "); printf("%c",c); } printf(" "); } return 0; }
codeup 1928 日期差值
#include<stdio.h> int run(int year) { if((year%4==0 && year%100!=0)||(year%400==0)) return 1; return 0; }//闰为true,1 int t[2][15]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}}; int main() { int year1,year2,month1,month2,day1,day2,num1,num2; while(scanf("%d%d",&num1,&num2)!=EOF) { int ans=1; if(num1>num2){ int temp=num1; num1=num2; num2=temp; }//num1<=num2 day1=num1%100; num1=num1/100; month1=num1%100; year1=num1/100; day2=num2%100; num2=num2/100; month2=num2%100; year2=num2/100; while(year2-year1>1) { if((month1==1)||(month1==2 && day1!=29)) ans=ans+365+run(year1); else if(month1==2 && day1==29) { day1=28; ans=ans+365; } else ans=ans+365+run(year1+1); year1++; } while(year2!=year1 || month2!=month1 || day2!=day1) { day1++; ans++; if(day1>t[run(year1)][month1]) { day1=1; month1++; if(month1==13) { month1=1; year1++; } } } printf("%d ",ans); } return 0; }
PAT A1022 D进制的A+B
#include<stdio.h> int main() { int a,b,d; scanf("%d %d %d",&a,&b,&d); int num=a+b; int temp=0; int ans[100]; while(num){ ans[temp++]=num%d; num=num/d; } for(int i=temp-1;i>=0;i--) printf("%d",ans[i]); if(temp==0) printf("0"); return 0; }
PAT B1009 说反话
#include<stdio.h> #include<string.h> int main() { char ans[80][100]; int num=0; while(scanf("%s",ans[num])!=EOF){ num++; } for(int i=num-1;i>0;i--) printf("%s ",ans[i]); printf("%s",ans[0]); return 0; }
PAT A1025 PAT Ranking
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct student{ int score; int local_rank; int final_rank; int location; char id[15]; }stu[30005]; bool cmp(student a,student b){ if(a.score!=b.score) return a.score>b.score; return strcmp(a.id,b.id)<0; } int main() { int n,localnum=0,stunum=0,temp;//localnum从1开始有效,stu从0开始 scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&temp); localnum++; int templocal=stunum; for(int j=1;j<=temp;j++) { scanf("%s %d",stu[stunum].id,&stu[stunum].score); stu[stunum].location=localnum; stunum++; } sort(stu+templocal,stu+stunum,cmp); stu[templocal].local_rank=1; for(int j=templocal+1;j<=stunum-1;j++) { if(stu[j].score==stu[j-1].score) stu[j].local_rank=stu[j-1].local_rank; else stu[j].local_rank=j-templocal+1; } } sort(stu,stu+stunum,cmp); stu[0].final_rank=1; for(int i=1;i<=stunum-1;i++) { if(stu[i].score==stu[i-1].score) stu[i].final_rank=stu[i-1].final_rank; else stu[i].final_rank=i+1; } printf("%d ",stunum); for(int i=0;i<=stunum-1;i++) printf("%s %d %d %d ",stu[i].id,stu[i].final_rank,stu[i].location,stu[i].local_rank); return 0; }
luogu P1706 全排列
#include<stdio.h> int n,P[100],hashTable[100]={0}; void generateP(int x){ if(x==n+1) { for(int i=1;i<=n;i++) printf("%5d",P[i]); printf(" "); return ; } for(int i=1;i<=n;i++) { if(hashTable[i]==0) { hashTable[i]=1; P[x]=i; generateP(x+1); hashTable[i]=0; } } } int main() { scanf("%d",&n); generateP(1); return 0; }
luogu P1219 n皇后
#include<stdio.h> int n,P[100],hashTable[100]={0},left[100]={0},right[100]={0},ans=0; void generateP(int x) { if(x==n+1) { ans++; if(ans>3) return; for(int i=1;i<=n-1;i++) { printf("%d ",P[i]); } printf("%d ",P[n]); return; } for(int i=1;i<=n;i++) { if(hashTable[i]==0 && left[x-i+30]==0 && right[x+i]==0) { hashTable[i]=1; left[x-i+30]=1; right[x+i]=1; P[x]=i; generateP(x+1); hashTable[i]=0; left[x-i+30]=0; right[x+i]=0; } } } int main() { scanf("%d",&n); generateP(1); printf("%d",ans); return 0; }
PAT A1020 月饼
#include<stdio.h> #include<algorithm> using namespace std; struct mooncake{ double kc; double market; double per; }m[1005]; bool cmp(mooncake a,mooncake b) { return a.per>b.per; } int main() { int n,d; double ans=0; scanf("%d %d",&n,&d); for(int i=1;i<=n;i++) scanf("%lf",&m[i].kc); for(int i=1;i<=n;i++) { scanf("%lf",&m[i].market); m[i].per=m[i].market/m[i].kc; } sort(m+1,m+1+n,cmp); int tempnow=1; while(d>0 && tempnow<=n) { if(m[tempnow].kc>d) { ans+=m[tempnow].per*d; break; } else { ans+=m[tempnow].market; d=d-m[tempnow].kc; tempnow++; } } printf("%.2f",ans); return 0; }
PAT A1023 组个最小数
#include<stdio.h> int main() { int a[15]; for(int i=0;i<=9;i++) scanf("%d",&a[i]); for(int i=1;i<=9;i++) { if(a[i]!=0) { a[i]--; printf("%d",i); break; } } for(int i=0;i<=9;i++) { while(a[i]!=0) { printf("%d",i); a[i]--; } } return 0; }
luogu P1226 快速幂
注意 底数为0返回0不是1,各个数计算出现新乘法要mod,若底数比取余的数大,先a mod m,避免进去计算数值过大。能整除时,要先算出来结果再结果乘,不然部分函数会被多次调用
#include<stdio.h> typedef long long LL; LL binaryPow(int a,int b,int m) { if(a==0) return 0; if(b==0) return 1; if(b==1) return a; if(b%2==0) { LL temp=binaryPow(a,b/2,m)%m; return (temp*temp)%m; } else return ((a*binaryPow(a,(b-1),m))%m); return 1; } int main() { int b,p,k; scanf("%d %d %d",&b,&p,&k); printf("%d^%d mod %d=%lld",b,p,k,binaryPow(b%k,p,k)); return 0; }
归并排序
注意,合并的过程还有复制的过程,两个的下标要同时进行改变哦
#include<stdio.h> int a[100005],ans[100005]; void merge(int A[],int l1,int r1,int l2,int r2){ int temp1=l1,temp2=l2; int ansnum=0; while(temp1<=r1 && temp2<=r2){ if(A[temp1]<=A[temp2]){ ans[ansnum++]=A[temp1++]; } else ans[ansnum++]=A[temp2++]; } while(temp1<=r1) ans[ansnum++]=A[temp1++]; while(temp2<=r2) ans[ansnum++]=A[temp2++]; for(int i=0;i<=ansnum-1;i++) A[l1++]=ans[i]; } void mergeSort(int A[],int left,int right){ if(left>=right) return; int mid=(left+right)/2; mergeSort(A,left,mid); mergeSort(A,mid+1,right); merge(A,left,mid,mid+1,right); } int main() { int n; scanf("%d",&n); for(int i=0;i<=n-1;i++) scanf("%d",&a[i]); mergeSort(a,0,n-1); printf("%d",a[0]); for(int i=1;i<=n-1;i++) printf(" %d",a[i]); return 0; }
快速排序
注意Partition最后要把最开始选定的值赋给A[left],另外没优化过的快速排序在luogu会TLE,归并不会
俩指针往中间靠近的过程中,也要时刻判断不要越界
#include<stdio.h> int a[100005]; int Partition(int A[], int left, int right){ int l=left,r=right; int temp=A[left]; while(l<r){ while(r>l && A[r]>=temp) r--; if(l!=r) A[l++]=A[r]; while(r>l && A[l]<=temp) l++; if(l!=r) A[r--]=A[l]; } A[l]=temp; return l; } void Partitionsort(int A[], int left, int right){ if(left<right) { int pos=Partition(A,left,right); Partitionsort(A,left,pos-1); Partitionsort(A,pos+1,right); } } int main() { int n; scanf("%d",&n); for(int i=0;i<=n-1;i++) scanf("%d",&a[i]); Partitionsort(a,0,n-1); printf("%d",a[0]); for(int i=1;i<=n-1;i++) printf(" %d",a[i]); return 0; }
归并排序非递归
step的选值,是要保证r1最后能够覆盖全部元素的,即r1=n-1,再加上step必偶数,-1可忽略
#include<stdio.h> #include<algorithm> using namespace std; int a[100005],ans[100005],n; void mergeNum(int A[],int l1,int r1,int l2,int r2){ int temp1=l1,temp2=l2,ansnum=0; while(temp1<=r1 && temp2<=r2){ if(A[temp1]<=A[temp2]){ ans[ansnum++]=A[temp1++]; } else ans[ansnum++]=A[temp2++]; } while(temp1<=r1) ans[ansnum++]=A[temp1++]; while(temp2<=r2) ans[ansnum++]=A[temp2++]; for(int i=0;i<=ansnum-1;i++) A[l1++]=ans[i]; return ; } void mergeSort(int A[], int left, int right){ if(left>=right) return; int mid=(left+right)/2; mergeSort(A,left,mid); mergeSort(A,mid+1,right); mergeNum(A,left,mid,mid+1,right); } void mergeSort2(int A[], int left, int right){ for(int step=2;step/2<=n-1;step=step*2) { int l1=left; while(l1<=n-1){ int r1=(l1+l1+step-1)/2; int l2=r1+1; if(l2>n-1) break; int r2=min(l1+step-1,n-1); mergeNum(A,l1,r1,l2,r2); l1=r2+1; } } } int main() { scanf("%d",&n); for(int i=0;i<=n-1;i++) scanf("%d",&a[i]); mergeSort2(a,0,n-1); printf("%d",a[0]); for(int i=1;i<=n-1;i++) printf(" %d",a[i]); return 0; }
PAT B1040 有几个PAT
#include<stdio.h> #include<string.h> int main() { long long ans=0; char s[100005]; scanf("%s",s); int p[100005]={0}; int t[100005]={0}; int len=strlen(s); if(s[0]=='P') p[0]=1; for(int i=1;i<len;i++) { if(s[i]=='P') p[i]=p[i-1]+1; else p[i]=p[i-1]; } if (s[len-1]=='T') t[len-1]=1; for(int i=len-2;i>=0;i--) { if(s[i]=='T') t[i]=t[i+1]+1; else t[i]=t[i+1]; } for(int i=0;i<=len-1;i++) { if(s[i]=='A') { ans=ans+p[i]*t[i]; } } printf("%lld",ans%1000000007); return 0; }
PAT A1060 Are They Equal
- 整个过程都要注意是不是在字符长度内
- 用string的话不要直接给下标对应位置赋值,用+拼接好一点
- s.erase(pos,length),删除某个位置开始的长度为length的字符串
- 注意特判0,因为去掉前导0以后有可能后面没数了
- 如果string作为参数,那么要使用引用(不用引用会出错,和数组不一样哦),或者直接作为返回值,两种做法都写出来了
- 整体思路:首先去掉前导0,之后,看是abcd.ef还是0.abcd这种的,分别进入判断,如果是前一种,那么找到.的位置,在找的过程中确定e,如果是后一种,看第一个非0有多少,来确定e
#include<stdio.h> #include<iostream> #include<string> int n; using namespace std; /*string deal(string s,int &e){ string ans="0."; e=0; while(s.length()!=0 && s[0]=='0') s.erase(s.begin()); if(s.length()==0){ e=0; for(int i=1;i<=n;i++) ans+='0'; return ans; } if(s[0]=='.'){ s.erase(s.begin()); while(s.length()!=0 && s[0]=='0') { s.erase(s.begin()); e--; } if(n<=s.length()){ for(int i=1;i<=n;i++) ans+=s[i-1]; } else{ for(int i=1;i<=s.length();i++) ans+=s[i-1]; for(int i=s.length()+1;i<=n;i++) ans+='0'; } } else{ int temp=0; while(temp<=s.length()-1 && s[temp]!='.'){ e++; temp++; } if(temp<=s.length()-1 && s[temp]=='.') s.erase(temp,1); if(n<=s.length()) { for(int i=1;i<=n;i++) ans+=s[i-1]; } else{ for(int i=1;i<=s.length();i++) ans+=s[i-1]; for(int i=s.length()+1;i<=n;i++) ans+='0'; } } return ans; }*/ void deal(string s,int &e, string &ans){ //string ans="0."; ans="0."; e=0; while(s.length()!=0 && s[0]=='0') s.erase(s.begin()); if(s.length()==0){ e=0; for(int i=1;i<=n;i++) ans+='0'; return ; } if(s[0]=='.'){ s.erase(s.begin()); while(s.length()!=0 && s[0]=='0') { s.erase(s.begin()); e--; } if(n<=s.length()){ for(int i=1;i<=n;i++) ans+=s[i-1]; } else{ for(int i=1;i<=s.length();i++) ans+=s[i-1]; for(int i=s.length()+1;i<=n;i++) ans+='0'; } } else{ int temp=0; while(temp<=s.length()-1 && s[temp]!='.'){ e++; temp++; } if(temp<=s.length()-1 && s[temp]=='.') s.erase(temp,1); if(n<=s.length()) { for(int i=1;i<=n;i++) ans+=s[i-1]; } else{ for(int i=1;i<=s.length();i++) ans+=s[i-1]; for(int i=s.length()+1;i<=n;i++) ans+='0'; } } return ; } int main() { string s1,s2,ans1,ans2; int e1,e2; int temp=1; cin>>n>>s1>>s2; //ans1=deal(s1,e1); //ans2=deal(s2,e2); deal(s1,e1,ans1); deal(s2,e2,ans2); if(ans1==ans2){ cout<<"YES "<<ans1<<"*10^"<<e1; } else{ cout<<"NO "<<ans1<<"*10^"<<e1<<" "<<ans2<<"*10^"<<e2; } return 0; }
codeup 1918 简单计算器
- 先把中缀表达式转换成后缀表达式,再直接处理后缀表达式完成计算。
- 中缀转后缀的处理办法:
- 整个表达式首先以字符串的形式读入进来,getline(cin,str)可以连着空格一起读入,再借助迭代器it遍历一次,使用erase去掉空格
- 使用一个栈来存储表达式中的符号,使用队列来存后缀表达式
- 按顺序访问中缀表达式,如果遇到了数,直接加入后缀表达式中。
- 如果遇到的是符号,跟操作符栈的栈顶比较一下,这个符号如果优先级比栈顶的高,那么压入栈中,如果低或者相同,弹出栈顶运算符,把它放到队列中,不断弹出直到它是优先级最高的运算符,压栈
- 字符都处理完成以后,把栈里面的元素弹出,加入队列。
- 后缀的处理方法:
- 这里是用队列处理的,如果是数,压入栈,如果是符号,从栈中弹出来两个操作符,然后把结果压入栈中。
- 全部处理结束以后,栈里面的那个数就是结果
- 其它注意:
- 多个输入数据的情况下,记得每次开始之前清空栈,因为栈会被处理后缀表达式队列的时候重复使用,肯定里面会有剩余的东西的
- 关于拓展:这个是没有括号的版本,如果遇到有括号,那么左括号的优先级设置为最低(一个符号来的时候判断,如果栈顶优先级大于等于当前,那么栈顶进入后缀中),也就是,在遇到右括号之前其它的符号都可以进栈,一旦遇到右括号,弹出离它最近的左括号之间的所有符号,左右括号不需要写在后缀表达式里面,就是正确的运算顺序。
#include<iostream> #include<stack> #include<queue> #include<string> #include<map> using namespace std; struct node{ double num; char op; bool flag;//true是数 false是符 }; string str; stack<node>s; queue<node>q; map<char,int>op; void Change(){ double num; node temp; for(int i=0;i<str.length();){ if(str[i]>='0'&&str[i]<='9'){ temp.flag=true; temp.num=str[i]-'0'; i++; while(i<str.length() && str[i]>='0' && str[i]<='9'){ temp.num=temp.num*10+(str[i]-'0'); i++; } q.push(temp); } else{ temp.flag=false; while(!s.empty() && op[str[i]]<=op[s.top().op]){ q.push(s.top()); s.pop(); } temp.op=str[i]; s.push(temp); i++; } } while(!s.empty()){ q.push(s.top()); s.pop(); } } double Cal(){ double ans,temp1,temp2; node cur,temp; while(!q.empty()){ cur=q.front(); q.pop(); if(cur.flag==true){ s.push(cur); } else{ temp2=s.top().num; s.pop(); temp1=s.top().num; s.pop(); temp.flag=true; if(cur.op=='+'){ temp.num=temp1+temp2; } else if(cur.op=='-'){ temp.num=temp1-temp2; } else if(cur.op=='*'){ temp.num=temp1*temp2; } else temp.num=temp1/temp2; s.push(temp); } } return s.top().num; } int main(){ op['+']=op['-']=1; op['*']=op['/']=2; while(getline(cin,str), str!="0"){ for(string::iterator it=str.begin();it!=str.end();it++) { if(*it==' '){ str.erase(it); } } while(!s.empty()) s.pop(); Change(); double ans=Cal(); printf("%.2f ",ans); } return 0; }
PAT A1032
- 这个题要用静态链表 给一个全都标记了以后,开始访问第二条链表,遇到的第一个就是结果。
- 不能舍弃其它数据 只看最后一个点 然后遇到一样的就作为输出结果,因为实际数据中可能会出现:他们在中途相遇 然后分开 再相遇 这时候就会导致可能会把第二次相遇的那个位置作为结果输出出来。
- PAT的题不能完全依照题目描述,要考虑,空点,无效点,多次交叉各类情况,尽量先思考要考到的知识点,再去想题目,自己想出来的简单方法很可能有问题。
#include<stdio.h> #include<iostream> #include<string.h> struct node{ char data; int next; bool flag; }a[100010]; int main(){ int head1,head2,num; int temp1,temp2; char tempchar; int ans=-1; for(int i=0;i<100010;i++) a[i].flag=false; scanf("%d %d %d",&head1,&head2,&num); for(int i=1;i<=num;i++){ scanf("%d %c %d",&temp1,&tempchar,&temp2); a[temp1].data=tempchar; a[temp1].next=temp2; } for(int i=head1;i!=-1;i=a[i].next){ a[i].flag=true; } for(int i=head2;i!=-1;i=a[i].next){ if(a[i].flag==true) { ans=i; break; } } if(ans==-1) printf("-1 "); else printf("%05d ",ans); return 0; }
PAT A1052
- 给出来的点不一定都在链表中,要判断一下,不在的点不需要输出,在判断的过程中统计在里面的点的个数。最后输出的是在里面的(对应第二个测试点)
- 特判,如果没有点在里面,要特殊输出 不然会越界(对应第五个测试点)
- 这类题要考察的就是链表,所以肯定会有不在里面的和空的情况。解题注意。
- 前面那个cmp 先判断temp1.flag==false return false 再判断temp2.flag==false return true也是可以的 但是倒过来会出错 不知道为什么。待补充。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; struct node{ int address; int data; int next; bool flag; }a[100010]; bool cmp(node temp1,node temp2){ /*if(temp2.flag==false) return true; if(temp1.flag==false) return false;*/ if(temp1.flag==false||temp2.flag==false) return temp1.flag>temp2.flag; return temp1.data<temp2.data; } int main(){ int num,head; int temp1,temp2,temp3; for(int i=0;i<100010;i++) { a[i].flag=false; } scanf("%d %d",&num,&head); for(int i=1;i<=num;i++){ scanf("%d %d %d",&temp1,&temp2,&temp3); a[temp1].address=temp1; a[temp1].data=temp2; a[temp1].next=temp3; //a[temp1].flag=true; } int count=0; for(int i=head;i!=-1;i=a[i].next) { a[i].flag=true; count++; } if(count==0){ printf("0 -1"); return 0; } sort(a,a+100010,cmp); for(int i=0;i<count;i++){ a[i].next=a[i+1].address; } a[count-1].next=-1; printf("%d %05d ",count,a[0].address); for(int i=0;i<count-1;i++) printf("%05d %d %05d ",a[i].address,a[i].data,a[i].next); printf("%05d %d -1 ",a[count-1].address,a[count-1].data); return 0; }