CCF-NOIP-2018 提高組(複賽) 模擬試題(一)

来源:https://www.cnblogs.com/Chen574118090/archive/2018/10/28/9866893.html
-Advertisement-
Play Games

T1 帽子戲法 問題描述 小 Y 有一個$n n n$的“帽子立方體” ,即一個$n$層的立方體,每層的帽子都 可以排成$n n$的矩陣。 “帽子立方體”中的每一個帽子都有一個顏色,顏色共 26 種,用 26 個大寫字母來表示。 現在,小 Y 邀請小 F 來表演她的帽子戲法。小 F 會 $2$ 種帽 ...


T1 帽子戲法

問題描述

小 Y 有一個\(n*n*n\)的“帽子立方體” ,即一個\(n\)層的立方體,每層的帽子都
可以排成\(n*n\)的矩陣。 “帽子立方體”中的每一個帽子都有一個顏色,顏色共 26
種,用 26 個大寫字母來表示。
現在,小 Y 邀請小 F 來表演她的帽子戲法。小 F 會 \(2\) 種帽子戲法:

  1. 指定一個長方體形狀的區域,將指定區域內的所有帽子全部變成指定的
    顏色。
  2. 指定一個長方體形狀的區域,將指定區域內所有指定顏色帽子全部變成
    綠色(用大寫字母\(G\)表示) 。
    小Y很喜歡綠色, 所以初始時立方體內的所有帽子都是綠色的。 不僅如此,
    小Y還會時不時地提出問題:他會指定一個長方體形狀的區域,並詢問在這個
    區域內有多少綠色的帽子。
    小Y的帽子琳琅滿目,請你來幫他數一數吧!

    輸入格式

    第一行 2 個正整數\(n,Q\),分別描述立方體的大小、以及小 F 表演帽子戲法和
    小 Y 提問的總次數。
    接下來Q行,每行第一個數\(op(0 ≤ op ≤ 2)\)表示這次詢問或帽子戲法的類型。
    \(op = 0\),表示這是小 Y 的一個提問,接下來 6 個正整數描述詢問指定的
    區域。
    \(op = 1\),接下來 6 個正整數表示帽子戲法指定的區域,之後一個大寫字母
    /%0表示小 F 會把指定區域內的所有帽子都變成\(col\)顏色。
    \(op = 2\), 接下來 6 個正整數表示帽子戲法指定的區域, 表示小 F 會把指定
    區域內的所有帽子都變成綠色。
    描述一個區域的方法為:用 6 個整數\(x_0,y_0,z_0,x_1,y_1,z_1\) 表示從第\(x_0\)層至第\(x_1\)
    層,從第\(y_0\)行至第\(y_1\)行,從第\(z_0\)列至第\(z_1\)列的區域(層、行、列編號的範圍都是
    1…n) 。

    輸出格式

    對於每個詢問,輸出一行一個整數表示答案。

    樣例

    樣例輸入
    3 5
    1 2 2 2 3 3 3 B
    1 1 3 2 3 3 2 R
    0 1 1 1 3 3 3
    2 3 3 3 3 3 3 B
    0 2 1 3 3 3 3
樣例輸出
18
3

數據範圍

對於 10%的數據,保證\(n=1\)
對於另外 10%的數據,保證只有詢問操作,即保證\(op=0\)
對於 30%的數據,保證\(n≤ 5,Q ≤ 10\)
對於 100%的數據,保證\(n ≤ 40,Q ≤ 200\)

題解

看一下數據範圍就應該知道是暴力的吧。\(maxn*maxn*maxn*maxQ=12800000\),排除每一次查詢、更改操作全部為最大操作的情況可知,\(O(n^3)\)可解
貼出代碼

#include<bits/stdc++.h>
#define maxn 405
using namespace std;
int n,q,ans;
int x1,z1,x2,y2,z2;
int y01,cmd;
char cas;
char a[maxn][maxn][maxn];
int main(){
    //freopen("hat.in","r",stdin);
    //freopen("hat.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>q;
    for(register int i=0;i<=n;i++){
        for(register int j=0;j<=n;j++){
            for(register int k=0;k<=n;k++)a[i][j][k]='G';
        }
    }
    while(q--){
        cin>>cmd;
        if(cmd==0){
            ans=0;
            cin>>x1>>y01>>z1>>x2>>y2>>z2;
            //cout<<x1<<" "<<y01<<" "<<z1<<" "<<x2<<" "<<y2<<" "<<z2<<endl;
            for(register int i=x1;i<=x2;i++){
                for(register int j=y01;j<=y2;j++){
                    for(register int k=z1;k<=z2;k++){
                        //cout<<"now:"<<i<<" "<<j<<" "<<k<<" "<<a[i][j][k]<<endl;
                        if(a[i][j][k]=='G')ans++;
                    }
                }
            }
            cout<<ans<<endl;
        }
        else if(cmd==1){
            cin>>x1>>y01>>z1>>x2>>y2>>z2;
            //cout<<x1<<" "<<y01<<" "<<z1<<" "<<x2<<" "<<y2<<' '<<z2<<endl;
            cin>>cas;
            for(register int i=x1;i<=x2;i++){
                for(register int j=y01;j<=y2;j++){
                    for(register int k=z1;k<=z2;k++){
                        a[i][j][k]=cas;
                    }
                }
            }
        }
        else if(cmd==2){
            cin>>x1>>y01>>z1>>x2>>y2>>z2;
            //cout<<x1<<" "<<y01<<" "<<z1<<" "<<x2<<" "<<y2<<' '<<z2<<endl;
            cin>>cas;
            for(register int i=x1;i<=x2;i++){
                for(register int j=y01;j<=y2;j++){
                    for(register int k=z1;k<=z2;k++){
                        if(a[i][j][k]==cas){
                            a[i][j][k]='G';
                            //cout<<i<<" "<<j<<" "<<k<<" "<<a[i][j][k]<<endl;
                        }
                    }
                }
            }
        }
    }
    return 0;
}

T2 最大隊列

問題描述

給定一個長度為\(n\)的排列(共包含\(n\)個整數,每個數取值範圍\(1\)\(n\)之間,且每個正整數出現並只出現一次)。藉助一個棧,依次將這個排列的每個元素進棧,併在合適的時候出棧,可以得到不同的出棧序列。不同的操作會帶來不同的出棧序列,請你求出在所有可能的方案中,字典序最大的出棧序列。

輸入格式

輸入數據共包括兩行。
第一行包含一個正整數\(n\),表示給定的排列的長度。
第二行包含\(n\)個正整數,描述給定的序列。

輸出格式

僅一行,共\(n\)個整數,表示你計算出的出棧序列。

樣例

樣例輸入1
4
4 2 1 3
樣例輸出1
4 3 1 2
樣例輸入2
10
4 5 1 2 6 10 7 8 3 9
樣例輸出2
10 9 3 8 7 6 2 1 5 4

數據範圍

所有測試點的數據規模與約定如上

題解

先說說自己的錯誤思路。先將所有數據排序,然後為了讓字典序儘量大則每次選取當前沒有被選取的最大值。同時我們維護一個上一次選取的數的位置\(lastp\),若\(lastp\)的值比當前我們要出棧的元素的位置的值要小我們則直接讓當前元素出棧,否則我們從將\(lastp\)到當前位置\(i\)的所有元素全部出棧。在一定程度上這樣的思路是正確的,但是我們如果這樣做就考慮漏了一種情況,即當我們先輸出元素比我們從\(lastp\)輸出到\(i\)時中間值的字典序要小,則整體字典序會比正確答案偏小。
上40分代碼

#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
int n;
int a[maxn];
struct edge{
    int a;
    int flag;
}E[maxn];
bool cmp(edge a,edge b){
    if(a.a!=b.a)return a.a>b.a;
    return a.flag<b.flag;
}
set<int> save;
int lastp=-1;
int out[maxn],note=1;
//map<int,int> jump;
int main(){
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    n=read();
    //cout<<n<<endl;
    for(register int i=1;i<=n;i++){
        a[i]=read();
        //cout<<a[i]<<" ";
        E[i].a=a[i];
        E[i].flag=i;
    }
    sort(E+1,E+1+n,cmp);
    for(register int i=1;i<=n;i++){
        if(save.count(E[i].a))continue;
        if(lastp<E[i].flag){
            out[note]=E[i].a;
            save.insert(E[i].a);
            note++;
            lastp=E[i].flag;
        }
        else{
            for(register int j=lastp-1;j>=E[i].flag;j--){
                if(save.count(a[j]))continue;
                out[note]=a[j];
                note++;
                save.insert(a[j]);
                //jump[j]=max(jump[j],lastp-1);
            }
            lastp=E[i].flag;
        }
    }
    for(register int i=1;i<note;i++){
        printf("%d",out[i]);
        if(i!=note-1)printf(" ");
    }
    return 0;
}

事實上,為了將上述情況納入考慮範圍內,我們選擇使用線上的演算法。我們令當前棧頂的元素為\(x\),並使所有還沒有入棧的元素中的最大值\(y\)。當\(x\le y\)時我們不斷入棧,直到情況不滿足為止。此時則將y直接扔出去即可。當沒有比棧頂元素更大的值時我們就不再入棧,而一直彈出棧頂元素直到滿足條件或沒有元素位置。由於每次查詢最大值時的複雜度為\(O(n)\),遍歷一次的複雜度為\(O(n)\),總複雜度則為\(O(n^2)\)
朴素\(O(n^2)\)代碼如下

#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
int n;
int a[maxn];
int maxnow;
int getmax(int now){
    int cas=-1;
    for(register int i=now;i<=n;i++)cas=max(cas,a[i]);
    return cas;
}
stack<int> box;
int out[maxn],note=1;
int main(){
    //freopen("1.txt","r",stdin);
    n=read();
    for(register int i=1;i<=n;i++)a[i]=read();
    for(register int i=1;i<=n;i++){
        //cout<<box.top()<<endl;
        if(box.empty()){
            box.push(a[i]);
            continue;
        }
        maxnow=getmax(i);
        if(box.top()>=maxnow){
            out[note]=box.top();
            //cout<<out[note]<<" ";
            box.pop();
            note++;
            i--;
            continue;
        }
        box.push(a[i]);
    }
    while(!box.empty()){
        out[note]=box.top();
        //cout<<out[note]<<" ";
        box.pop();
        note++;
    }
    //cout<<endl;
    for(register int i=1;i<note;i++)printf("%d ",out[i]);
    return 0;
}

當然朴素演算法並不能滿足\(n=200000\)等大數據的要求,因此我們要對演算法進行優化。事實上我們可以減少取最大值的次數——我們只在開始時和每一次最大值被pop出棧時才重新取一次最大值

for(register int i=1;i<=n;i++)a[i]=read(),maxnow=max(maxnow,a[i]);
for(register int i=1;i<=n;i++){
        if(i==1){
            box.push(a[i]);
            continue;
        }
        if(box.top()>=maxnow){
            maxnow=getmax(i);
            out[note]=box.top();
            box.pop();
            note++;
            i--;
            continue;
        }
        box.push(a[i]);
    }

完整代碼

#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
int n;
int a[maxn];
int maxnow;
int getmax(int now){
    int cas=-1;
    for(register int i=now;i<=n;i++)cas=max(cas,a[i]);
    return cas;
}
stack<int> box;
int out[maxn],note=1;
int main(){
    //freopen("1.txt","r",stdin);
    n=read();
    for(register int i=1;i<=n;i++)a[i]=read(),maxnow=max(maxnow,a[i]);
    for(register int i=1;i<=n;i++){
        if(box.empty()){
            box.push(a[i]);
            continue;
        }
        if(box.top()>=maxnow){
            maxnow=getmax(i);
            out[note]=box.top();
            //cout<<box.top()<<endl;
            box.pop();
            note++;
            i--;
            continue;
        }
        box.push(a[i]);
    }
    while(!box.empty()){
        out[note]=box.top();
        box.pop();
        note++;
    }
    for(register int i=1;i<note;i++)printf("%d ",out[i]);
    return 0;
}

T3 思考熊的馬拉松

題面描述

今年,\(n\)只思考熊參加了校園馬拉松比賽。馬拉松的賽道是環形的,每圈的
長度是:,完成比賽需要跑;圈。
比賽中,甲領先乙很長距離,繞過一圈或多圈後從後面追上了乙的現象叫做
“套圈” 。 套圈現象非常常見, 例如: 跑得比誰都快的\(S\)熊可以套某些熊 \(L-1\)圈;
\(U\) 熊經常進行日常耐力訓練,套圈次數和被套圈次數基本持平;而$ M$ 作為一隻
老年熊,則是被套\(L-1\)圈的那種。
與人不同的是, 思考熊在跑步時都是勻速運動。$ W$ 熊是這次比賽的計時員,
他統計了參賽的\(n\)只熊的速度\(v_1 ,v_2 ,…,v_n\)(其中最大的一個是\(S\)熊的速度) 。現
\(W\)熊希望你告訴他,當速度最快的\(S\)熊到達終點時,場上所有熊中總共發生
了多少次套圈現象。
註意:在\(S\)熊剛剛到達終點那一刻,如果甲恰好追上了乙,此時也算作甲將
乙套圈。

輸入格式

輸入的第一行包含兩個整數\(T,C\),分別表示這個測試點的組數和這個測試點的編號。對於測試數據,保證\(T=10\)
每組數據的第一行包含3個正整數\(n,A,L\),分別表示思考熊的只數、跑道每圈的長度和完成比賽所需要的圈數。保證\(A,L\le 10^8\)
第二行包含\(n\)個正整數\(v_1,v_2,...,v_n\)表示每隻思考熊的速度。保證這些數互不相同。

輸出格式

輸出\(T\)行,分別表示每組數據中所有熊發生的套圈總次數。

樣例

樣例輸入
1 0
3 2 6
1 2 3
樣例輸出
8

數據範圍

所有測試點的數據規模與約定如上

題解

這是一道數學題,去隔壁請一個數競大佬來吧。
首先我們已知比賽結束時間\(t_{end}\)一定是\(\frac{L*A}{v_{max}}\),則此時為了求出結束時間我們就先將所有熊的速度從大到小排序,然後求\(t_{end}=\frac{A*L}{v_1}\)即可知道能跑的最長時間。這時我們知道對於$ \forall v_1
\(<\) v_2 \(都一定有\) v_2 $ 套 $ v_1 k 圈的時間是$ t_k=\frac{Ak}{v_2-v_1} \(,則我們可以取\) t_k\le t_{end} \(為答案。則因此聯立方程組後可知,對於我們排序後的數列中\) \forall v_i和v_j \(,一定有\) a_{ij}=\frac{Aabs(v_i-v_j)}{v_{end}} \(。我們枚舉每一個數即可得到答案。複雜度即為\)O(n^2)$。

** 雖然$ \forall v $$ 都 $ \le 10^8 \(,但是\) \forall x=abs(v_1-v_2)L \(不一定滿足\) x \subseteq (1,10^8) $ !
貼出該題的部分分解法
(50)**

#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline long long read(){
    register char c=get();register long long f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
long long n,A,L;
long long v[maxn];
bool cmp(long long a,long long b){
    return a>b;
}
long long ans=0;
int main(){
    //freopen("2.txt","r",stdin);
    long long T,C;
    T=read();C=read();
    //cout<<1<<endl;
    while(T--){
        ans=0;
        n=read();A=read();L=read();
        for(register long long i=1;i<=n;i++)v[i]=read();
        if(n==1){
            puts("0");
            continue;
        }
        sort(v+1,v+1+n,cmp);
        for(register long long i=1;i<=n;i++){
            for(register long long j=i+1;j<=n;j++){
                ans+=(L*(v[i]-v[j]))/v[1];
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

緊接著我們繼續考慮更加一般的情況。
image
代碼如下

#include <bits/stdc++.h>
using namespace std;
typedef long long int64;
const int MAXN = 100005;
int n;
int64 L,A;
int64 a[MAXN], b[MAXN], c[MAXN];
inline int lowbit(int x) {
    return x & (-x);
}
void insert(int x) {
    for (int i = x; i <= n; i += lowbit(i)) c[i]++;
}
int getsum(int x) {
    int res = 0;
    for (int i = x; i; i -= lowbit(i)) res += c[i];
    return res;
}
int main() {
    //freopen ("running.in","r",stdin);
    //freopen ("running.out","w",stdout);
    int T, case_num;
    scanf("%d%d", &T, &case_num);
    while (T--) {
        scanf("%d%lld%lld", &n, &A, &L);
        int64 ans = 0;
        int64 maxv = 0;
        for (int i = 1; i <= n; i++) {
            c[i] = 0;
            scanf("%lld", &a[i]);
            maxv = max(maxv, a[i]);
            a[i] *= L;
        }
        sort(a + 1, a + n + 1);
        reverse(a + 1, a + n + 1);
        for (int i = 1; i <= n; i++) {
            ans += (a[i] / maxv) * (int64) (n - 2 * i + 1);
            a[i] %= maxv;
        }
        for (int i = 1; i <= n; i++) b[i] = a[i];
        sort(b + 1, b + n + 1);
        int m = int(unique(b + 1, b + n + 1) - (b + 1));
        for (int i = 1; i <= n; i++) {
            a[i] = int(lower_bound(b + 1, b + m + 1, a[i]) - b);
            ans -= getsum(a[i] - 1);
            insert(a[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 生成器的作用:一條一條輸出,輸出一個獲取一個,不像return,輸出後就馬上返回,不能執行後面的函數。 !!!send 獲取下一個值的效果和next基本一致,但是獲取下一個值時,要給上一個yield的位置傳遞一個數據。 !!!第一次使用生成器時,是用next獲取下一個值,最後一個yield不能接受外 ...
  • ThinkPHP5+小程式商城 網盤視頻 有需要聯繫我 QQ:1844912514 ...
  • 近日,有朋友向我求助一件小事兒,他在一個短視頻app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。這忙我得幫,少不得就抓包分析了一下這個app,找到了視頻的下載鏈接,幫他解決了這個小問題。 因為這個事兒,勾起了我另一個念頭,這不最近一直想把python爬蟲方面的知識梳理梳理嗎,乾脆藉機 ...
  • Thymeleaf是用於Web和獨立環境的現代伺服器端Java模板引擎。Thymeleaf的主要目標是將優雅的自然模板帶到您的開發工作流程中—HTML能夠在瀏覽器中正確顯示,並且可以作為靜態原型,從而在開發團隊中實現更強大的協作。Thymeleaf能夠處理HTML,XML,JavaScript,CS... ...
  • 個人的一些認識,希望能對初學Java的你,或者困惑於方法參數傳遞的你祈禱一絲幫助! 下麵是一些作者的個人觀點,如果有錯,歡迎各位大牛指出錯誤,灰常感謝您的觀看與支持... 今天學習Java的時候,看見書中提及方法參數傳遞 有按值傳遞 和按地址傳遞; 上面的源代碼是Java中的按值傳遞: 那什麼是引用 ...
  • python學習—字元編碼 例如漢字“中” 十進位:20013 二進位:01001110 00101101(unicode)/11100100 10111000 10101101(utf-8) 十六進位:u4e2d 八進位: ascii ASCII編碼是1個位元組 只能編碼純英文 節省空間 unico ...
  • list是C++標準模版庫(STL,Standard Template Library)中的部分內容。實際上,list容器就是一個雙向鏈表,可以高效地進行插入刪除元素。 使用list容器之前必須加上STL的list容器的頭文件:#include ...
  • 多線程 參數傳遞 1,值傳遞,拷貝一份新的給新的線程。線程1中有個int變數a,線上程1中啟動線程2,參數是a的值,這時就會拷貝a,線程1和線程2不共用a。 2,引用傳遞,不拷貝一份新的給新的線程。線程1中有個int變數a,線上程1中啟動線程2,參數是a的引用,這時就不會拷貝a,線程1和線程2共用a ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...