還有四天就要考PAT了,這幾天寫博客回顧一下常用的算法,臨時抱一下佛腳哈哈哈~
第一次寫,如有錯誤,請多指教哈~
排序篇
排序是程序員必備技能,也是基本功。不過pat貌似對排序的考察不多,好像就見到插排和歸併,其他的主要穿插在大模擬題中考察,並且可以通過封裝好的sort方法偷懶哈哈哈。
一、選擇和插排
void selectsort(){
for(int i=0;i<n;i++){
int index=i;
for(int j=i+1;j<n;j++){
if(a[j]<a[index]){
index=j;
}
}
swap(a[i],a[index]);
}
}
void insertsort(){
for(int i=1;i<n;i++){
int cur=a[i];
int j=i;
while(j>=1&&cur<a[j-1]){
a[j]=a[j-1];
j--;
}
a[j]=cur;
}
}
二、歸併排序
歸併排序要注意一下,遞歸和非遞歸的排序過程是不一樣的(被一道題坑過)。它的遞歸,是將左半部分先排好,再排右半部分,和教科書上的圖示是不一樣的過程,而非遞歸就和教科書上的一樣了。
//////////////////////////////////////歸併排序
void merge(int l1,int r1,int l2,int r2){
int temp[n];
int index=0;
while(l1<=r1&&l2<=r2){
if(a[l1]<a[l2])
temp[index++]=a[l1++];
else
temp[index++]=a[l2++];
}
while(l1<=r1)temp[index++]=a[l1++];
while(l2<=r2)temp[index++]=a[l2++];
for(int i=0;i<index;i++)
a[l1+i]=temp[i];
}
//遞歸
void mergesort(int left,int right){
if(left>right)
return;
int mid=(left+right)/2;
mergesort(left,mid);
mergesort(mid+1;right);
merge(left,mid,mid+1,right);
}
//非遞歸
void mergesort(){
for(int step=2;step/2<n;step*=2){
for(int i=0;i<n;i+=step){
int end=min(i+step,n-1);
int mid=i+step/2-1;
merge(i,mid,mid+1,end);
}
}
}
//////////////////////////////////////歸併排序
三、快速排序
//////////////////////////////////////快速排序
int partition(int left,int right){
int cur=a[left];
while(left<right){
while(left<right&&a[right]>temp)right--;
a[left]=a[right];
while(left<right&&a[left]<temp)left++;
a[right]=a[left];
}
a[left]=cur;
return left;
}
void quicksort(int left,int right){
if(left<right){
int mid=partition(left,right);
quicksort(left,mid-1);
quicksort(mid+1,right);
}
}
//////////////////////////////////////快速排序
四、二分查找
二分查找本身非常簡單,但是它的逼近思想可以擴展出很多應用,例如求根號2的近似數等。
int binarysearch(int left,int right,int data){
if(left>right)
return -1;
int mid=(left+right)/2;
if(a[mid]==data)
return mid;
else if(data<a[mid])
return binarysearch(left,mid-1);
else
return binarysearch(mid+1,right);
}
篇幅不夠,題目來湊!
1083 List Grades (25 分)
Given a list of N student records with name, ID and grade. You are supposed to sort the records with respect to the grade in non-increasing order, and output those student records of which the grades are in a given interval.
Input Specification:
Each input file contains one test case. Each case is given in the following format:
N
name[1] ID[1] grade[1]
name[2] ID[2] grade[2]
... ...
name[N] ID[N] grade[N]
grade1 grade2
where name[i]
and ID[i]
are strings of no more than 10 characters with no space, grade[i]
is an integer in [0, 100], grade1
and grade2
are the boundaries of the grade's interval. It is guaranteed that all the grades are distinct.
Output Specification:
For each test case you should output the student records of which the grades are in the given interval [grade1
, grade2
] and are in non-increasing order. Each student record occupies a line with the student's name and ID, separated by one space. If there is no student's grade in that interval, output NONE
instead.
Sample Input 1:
4
Tom CS000001 59
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
60 100
Sample Output 1:
Mike CS991301
Mary EE990830
Joe Math990112
Sample Input 2:
2
Jean AA980920 60
Ann CS01 80
90 95
Sample Output 2:
NONE
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
#include<queue>
using namespace std;
struct node{
string name,id;
int grade;
};
int num;
vector<node> result;
bool cmp(node &a,node &b){
return a.grade>b.grade;
}
int main(){
cin>>num;
for(int i=0;i<num;i++){
string name,id;
int grade;
cin>>name>>id>>grade;
node* temp=new node;
temp->name=name;
temp->id=id;
temp->grade=grade;
result.push_back(*temp);
}
int g1,g2;
cin>>g1>>g2;
sort(result.begin(),result.end(),cmp);
bool flag=false;
for(int i=0;i<result.size();i++){
if(result[i].grade>=g1&&result[i].grade<=g2){
flag=true;
cout<<result[i].name<<" "<<result[i].id<<endl;
}
}
if(!flag){
cout<<"NONE"<<endl;
}
return 0;
}