1. 程式人生 > >清北學堂(2019 4 28 ) part 1

清北學堂(2019 4 28 ) part 1

沒有 垂直 判斷回文 names pre say 必須 如果能 etc

今天主要用來鋪路,打基礎

枚舉

沒什麽具體算法講究,但要考慮更優的暴力枚舉方法,例如回文質數,有以下幾種思路:

1.挨個枚舉自然數,再一起判斷是否是回文數和質數,然而一看就不是最優

2.先枚舉質數再判斷回文,但質數顯然要比回文數要多,較下一種慢

3.先枚舉回文數再判質:

  (1).分別開數組,把每個元素當做一位數,如w[1]表示個位,w[2]表示十位等,如果能構成回文,再判質

  (2).枚舉最大數位數的一半,即分析1-600000之中的數只需枚舉後三位,將後三位翻轉形成回文數,再判質,顯然更優

洛谷原題,用的3-(1),其實效果與1相仿,就是少判斷幾次,很快ac了,顯然數據很水

搜索

這個真的沒有整的必要,畢竟最近學了,最近也整理過了(只會打模板QAQ)

貪心

貪心是一類思路的總稱,其實沒有像動態規劃,深搜廣搜,dijkstra一樣的公式,只是指這類題可以根據局部最優,推出全局最優

大佬曰:“貪心難的不是算法思路,而是如何證明這個算法思路是對的”

就像幾何證明題,你看它垂直,就是證不出來

貪心主要思路:

1.列些好像是對的的關系式,越多越好,當然如果直接有正確思路可以直接敲代碼了。。。

2.對於以上思路、關系式,盡力舉反例,卡掉越多思路剩下的正確率越高,除非你把自己的思路全部卡掉,對於這種情況,提供兩種方案:

  (1).放棄此題

  (2).取樣例過得多的算法,騙更多的分

其實貪心需要刷題來養成形成最優方案的思維

二分

講過,但具體並沒進行過代碼實現過,今天簡單練了下

粘個代碼:

#include<bits/stdc++.h>
using namespace std;
int n;         //數據總個數
int target;    //查詢目標
int l,r,mid;
int a[50005];
priority_queue<int,vector<int>,greater<int> > q; //用優先隊列排序,不用sort
int main(){
    scanf(
"%d%d",&n,&target); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); q.push(x); } for(int i=1;i<=n;i++){ a[i]=q.top(); q.pop(); } for(int i=1;i<=n;i++)printf("%d ",a[i]); puts(""); //好像puts比printf和cout快的多,就像getchar與scanf與cin l=1; r=n; while(l<=r){ //二分主體 mid=(l+r)>>1; if(a[mid]==target){ printf("%d\n",mid); return 0; } if(a[mid]>target) r=mid-1; //必須作加減處理,不然卡死循環 else if(a[mid]<target) l=mid+1; } printf("Why did u say that number?\n"); //蝙蝠俠老梗(無解情況) return 0; }

分治

好像就是遞歸??

用分治做出來過“冪次方”(題目傳送門)

(博客傳送門)

當時覺得自己a了道遞歸題好厲害。。。完全不知道這是分治

清北學堂(2019 4 28 ) part 1