【計劃執行報告】Day3 04-02 C++排序之旅
Day3 04-02 C++排序之旅
這是我:計劃執行的第3天
今天運行較平穩(除了11:00-12:00沒進行記錄外)。綜合執行的情況,計劃中存在的問題以及調整:①競賽訓練時間從40min增長爲60min,題量基本定爲1題,確保解決時間充足;②適當減少了部分時間段中的任務量,確保能完成;③確定了每日時間管理的循環點爲23:30左右; ④計劃中暫未留給專業課複習的時間(預計第8週週五後會開始考慮); ⑤沒有考慮鍛鍊時間; ⑥考慮到寫計劃執行報告的目的是用於記錄而不是展示知識細節,因此應該更精煉。故在此不再貼出某個較大topic的詳細知識(有關內容可能會專門地寫一篇blog); ⑦計劃的遊戲性(獎勵機制)暫未考慮。
近期計劃(03-31-04-12)
1.準備4月10日的機器學習最終報告——《暢想無監督學習》;查找文獻與知識補充:《機器學習——算法視角》、數學知識
2.完成專業課的作業(流體機械能轉化、生物質能,新能源熱利用可以往後稍稍);
3.備戰藍橋杯,爲此:①每天1h左右的刷題或者典型題攻克;②知識補充:《程序員的面試筆記:C/C++、算法、數據結構篇》
今日計劃表
實際時間分配
今日執行情況良好,目標基本實現(昨天睡得較晚,因此休息時間沒達到目標)
今日學習總結與反思
1.機器學習PCA視頻回顧
主成分分析(Principal Component Analysis)
1.兩個視角,本質相同:
①最大化數據投影的方差——儘可能全地保留數據的信息(已經推導);
②最小化原數據與投影數據間距離——儘可能減小數據信息損失(暫未能理解推導)
奇妙之處:兩種視角下非凸問題的全局極優解都能找到
涉及概念:
①矩陣的秩
②拉格朗日乘數法可以參考鏈接:https://blog.csdn.net/THmen/article/details/87366904
2.《程序員的面試筆記》五大排序算法實戰收穫
①直接插入排序 ②冒泡排序 ③簡單選擇排序 ④希爾排序 ⑤快速排序
①③④實現較快,②因爲是第一個寫的,且關於循環的界限有點混,因此花的時間比前三個多,⑤耗時最多
快排實現遇到的主要難題與收穫
- 基準元素的選擇——首元素、中間元素、末元素的三者取中後的操作(不要忘了將中值的元素與首元素交換)
- 遞歸的參數選擇與實現
- 兩種swap()寫法的區別:
- 方法1:第三元素tmp實現交換(常規,除了多用了一個變量外沒啥)
- 方法2:利用異或運算實現,該方法使用時要避免swap(x,x)這種情況,如果這樣那麼不論x變換前爲何值,最終都會變爲0
void swap(elemType& a,elemType& b){a^=b^=a^=b;}
實現代碼:
#include<iostream>
#include<string>
#include<ctime>
#define loop(i,x,y) for(i=x;i<y;i++)
#define printArr(a,n) for(int i=0;i<n;i++) cout<<a[i]<<" "
using namespace std;
typedef int elem;
enum Order{
Up,Down
};
void swap(elem&,elem&);
void bubbleSort(elem*,int,Order);
void insertSort(elem*,int,Order);
void selectSort(elem*,int,Order);
void shellSort(elem*,int,Order);
void quickSortArr(elem*,int,int,Order);
void quickSort(elem*,int,Order);
int main(){
//提高效率
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,i=5,j=6;
cin>>n;
elem* a=new elem[n];
loop(i,0,n)
cin>>a[i];
cout<<"order:";
int order; // 0 - up 1 -down
cin>>order;
Order ord=(Order)order;
cout<<"before:";
printArr(a,n);
cout<<endl<<"after:";
//bubbleSort(a,n,ord);
//insertSort(a,n,ord);
//selectSort(a,n,ord);
//shellSort(a,n,ord);
quickSort(a,n,ord);
printArr(a,n);
delete[] a;
return 0;
}
void swap(elem& a,elem& b){
a^=b^=a^=b; //慎用!不能發生swap(x,x);否則全變爲0
}
void bubbleSort(elem* array,int size,Order order){
int flag=1;
//up
if(order==Up){
for(int i=0;i<size-1&&flag;i++){
flag=0;
for(int j=0;j<size-i-1;j++){
if(array[j+1]<array[j]){ //判斷中的超維沒有問題
swap(array[j+1],array[j]); //這裏如果超維就會崩潰
flag=1;
}
}
}
}
else{
for(int i=0;i<size-1&&flag;i++){
flag=0;
for(int j=0;j<size-i-1;j++){
if(array[j+1]>array[j]){ //判斷中的超維沒有問題
swap(array[j+1],array[j]); //這裏如果超維就會崩潰
flag=1;
}
}
}
}
}
void insertSort(elem* array,int size,Order order){
if(order==Up){//從小到大,每次把較小的往前送
/*
for(int i=1;i<size;i++){
int index=i-1,flag=0;
while(index>=0&&array[index]>array[i]){
index--;flag=1;
}
if(flag){
int tmp=array[i];
for(int j=i;j>index+1;j--)
array[j]=array[j-1];
array[index+1]=tmp;
}
}
*/
for(int i=1;i<size;i++){
int tmp=array[i];
int j=i-1;
while(j>=0&&tmp<array[j]){
array[j+1]=array[j--];
}
array[j+1]=tmp;
}
}
else{
for(int i=1;i<size;i++){//從大到小
int index=i-1,flag=0;
while(index>=0&&array[index]<array[i]){
index--;flag=1;
}
if(flag){
int tmp=array[i];
for(int j=i;j>index+1;j--)
array[j]=array[j-1];
array[index+1]=tmp;
}
}
}
}
void selectSort(elem* array,int size,Order order){
if(order==Up){
for(int i=0;i<size-1;i++){
int tmp=i;
for(int j=i+1;j<size;j++){
if(array[j]<array[tmp])
tmp=j;
}
if(tmp!=i)
swap(array[i],array[tmp]);
}
}
else{
for(int i=0;i<size-1;i++){
int tmp=i;
for(int j=i+1;j<size;j++){
if(array[j]>array[tmp])
tmp=j;
}
if(tmp!=i)
swap(array[i],array[tmp]);
}
}
}
void shellSort(elem* array,int size,Order order){
int gap=size;
if(order==Up)
while(gap/2){
gap/=2;
int flag;
do{
flag=0;
for(int i=0;i<size-gap;i++)
if(array[i]>array[i+gap])
swap(array[i],array[i+gap]),flag=1;
}while(flag!=0);
}
else
while(gap/2){
gap/=2;
int flag;
do{
flag=0;
for(int i=0;i<size-gap;i++)
if(array[i]<array[i+gap])
swap(array[i],array[i+gap]),flag=1;
}while(flag!=0);
}
}
void quickSortArr(elem* array,int s,int t,Order order){
if(t<=s)
return;
//三者取中
int tar=s,mid=(s+t)/2;
if(array[tar]>=array[t]&&array[t]>=array[mid]||
array[tar]<=array[t]&&array[t]<=array[mid]){
tar=t;
}
else if(array[tar]>=array[mid]&&array[mid]>=array[t]||
array[tar]<=array[mid]&&array[mid]<=array[t]){
tar=mid;
}
if(s!=tar){
swap(array[s],array[tar]);
tar=s;//把中間元素放在第一個
}
if(order==Up){
int low,high;
low=s,high=t+1;
while(1){
//找出第一對位置不對的元素位置
do low++;
while(array[low]<=array[tar]&&low!=t);
do high--;
while(array[high]>=array[tar]&&high!=s);
if(low<high)
swap(array[low],array[high]);
else
break;
}
if(high!=s) //如果是異或運算交換值,則必須保證不是同一個變量
swap(array[high],array[s]);
quickSortArr(array,s,high-1,order);
quickSortArr(array,high+1,t,order);
}
else{
int low=s,high=t+1;
while(1){
//找出第一對位置不對的元素位置
do low++;
while(array[low]>=array[tar]&&low!=t);
do high--;
while(array[high]<=array[tar]&&high!=s);
if(low<high)
swap(array[low],array[high]);
else
break;
}
if(high!=s) //如果是異或運算交換值,則必須保證不是同一個變量
swap(array[high],array[s]);
quickSortArr(array,s,high-1,order);
quickSortArr(array,high+1,t,order);
}
}
void quickSort(elem* array,int size,Order order){
quickSortArr(array,0,size-1,order);
}
3.藍橋杯競賽模擬題典型BFS問題:“長草”
03-14模擬賽賽題第八題“長草”鏈接
自己的實現
時間複雜度O(NM)
關鍵:用隊列實現BFS,每一塊長草的地都只會判斷一次,月份在後的其隊列中的位置也一定靠後。
易錯點:cin.get()函數的用途(接收字符與濾去回車)
#include<iostream>
#include<queue>
using namespace std;
int land[1000][1000];
typedef struct ground{
int i,j;
int month;
}Block;
const int dx[]={0,-1,0,1};
const int dy[]={1,0,-1,0};
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,k;
cin>>n>>m;
char ch;
cin.get(ch);//回車
queue<Block> q;
for(int i=0;i<n;i++){
cin.get(ch);
for(int j=0;j<m;j++){
if(ch=='g'){
land[i][j]=1;
q.push({i,j,0});
}
cin.get(ch);
}
}
cin>>k;
while(!q.empty()){
Block b=q.front();
q.pop();
if(b.month>=k)//月份已到
continue;
for(int l=0;l<4;l++){
int nx=b.i+dx[l];
int ny=b.j+dy[l];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&land[nx][ny]==0){
land[nx][ny]=1;
q.push({nx,ny,b.month+1});
}
}
/*
//right
if(b.j+dy[0]<m&&land[b.i][b.j+dy[0]]==0){
land[b.i][b.j+dy[0]]=1;
q.push({b.i,b.j+dy[0],b.month+1});
}
if(b.j+dy[2]>=0&&land[b.i][b.j+dy[2]]==0){
land[b.i][b.j+dy[2]]=1;
q.push({b.i,b.j+dy[2],b.month+1});
}
if(b.i+dx[1]>=0&&land[b.i+dx[1]][b.j]==0){
land[b.i+dx[1]][b.j]=1;
q.push({b.i+dx[1],b.j,b.month+1});
}
if(b.i+dx[3]<n&&land[b.i+dx[3]][b.j]==0){
land[b.i+dx[3]][b.j]=1;
q.push({b.i+dx[3],b.j,b.month+1});
}
*/
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(land[i][j]){
cout<<"g";
}
else{
cout<<".";
}
}
cout<<endl;
}
return 0;
}