日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

基本算法总结篇

發(fā)布時(shí)間:2025/3/19 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基本算法总结篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基本算法總結(jié)篇

  • 位運(yùn)算
    • 飛行員兄弟
      • 解題思路:
      • 技巧
  • 遞歸
    • 分形
  • 分治
    • 平面最近點(diǎn)對(duì)
  • 二分
    • 防線
    • 趕牛入圈
      • 離散化
  • 中位數(shù)
    • 糖果傳遞【環(huán)形紙牌均分問題】
    • 士兵
  • 貪心
    • 耍雜技的牛
    • 任務(wù)
  • 前綴和
    • 最大子矩陣的和(二維列前綴和)

位運(yùn)算

飛行員兄弟

題目鏈接

解題思路:

對(duì)于棋盤的每一個(gè)開關(guān)都有開或者關(guān)兩種狀態(tài),所以總的狀態(tài)數(shù)為2162^{16}216.沒有超出int 的范圍,所以我們可以用一個(gè)整數(shù)來(lái)代表棋盤的狀態(tài)。意思是我們把4*4的矩陣變?yōu)橐粋€(gè)一維的形式每一位是0或者1。0表示開,1表示關(guān)(+)。在遍歷所有狀態(tài)的時(shí)候,第 i為為1就表示按下第i位的開關(guān),而按下開關(guān)之后的變化,我們可以有如下圖,直接異或一個(gè)值即可。之后檢驗(yàn)最后的狀態(tài)是否全開(全0)。

技巧

  • 因?yàn)楫惢驖M足結(jié)合律,所以我們不用一個(gè)一個(gè)的去異或每一行每一列的值,而是直接一次異或其總和即可。
  • 二維小標(biāo)與一維下標(biāo)之間的轉(zhuǎn)化。對(duì)于從0開始存的,二維小標(biāo)(i,j)變?yōu)橐痪S的公式是 i * n + j . 一維變?yōu)槎S則是, x = k /n , y = k % n;
  • 代碼:

    #include <bits/stdc++.h> using namespace std;typedef pair <int, int> PII; // 維護(hù)兩個(gè)元素vector<PII> res; // 儲(chǔ)存答案int state; // 狀態(tài)壓縮 1 表示 關(guān); 0 表示 開 int change[4][4];int get(int x, int y) // 求出二維矩陣 (x, y) 的編號(hào) {return 4 * x + y; }int main() {char stuc;for(int i = 0; i < 4; i ++) {for(int j = 0; j < 4; j ++) {cin >> stuc;if(stuc == '+') {state += 1 << get(i, j);// 因?yàn)楫?dāng)前的開關(guān)是關(guān)上的,// 所以用路徑壓縮的方式將 state 的當(dāng)前編號(hào)設(shè)為 1}}}for(int i = 0; i < 4; i ++) {for(int j = 0; j < 4; j ++) {for(int k = 0; k < 4; k ++){// 預(yù)處理九個(gè)數(shù)的異或值change[i][j] += 1 << get(i, k); change[i][j] += 1 << get(k, j);// 處理 i 行 j 列的異或值}change[i][j] -= 1 << get(i, j);// 減去相同的元素}}for(int k = 0; k < (1 << 16) ; k ++) { // 枚舉每個(gè)開關(guān)按或不按的所有狀態(tài)int now = state;// 保存原來(lái)的矩陣vector<PII> path;for(int i = 0; i < 16; i ++) {if( (k >> i) & 1) {// 如果 k 沒關(guān)時(shí)int x = i / 4, y = i % 4;// 找出 k的 (x, y) 的坐標(biāo)now ^= change[x][y]; // 因?yàn)橐呀?jīng)預(yù)處理過(guò)了path.push_back({x, y}); // 加入臨時(shí)答案}}if(!now && ( res.empty() || res.size() > path.size())){// 滿足條件并選最小的數(shù)res = path;}}cout << res.size() <<endl; // 輸出元素個(gè)數(shù)for(int i = 0; i < res.size(); i ++) {// 輸出方案數(shù)cout<< res[i].first + 1<<" "<< res[i].second + 1 <<endl;} }

    遞歸

    分形

    題目鏈接

    解題思路:

    • 這道題目思維難度不是很大,我們主要是要看清題目的輸出格式,其實(shí)當(dāng)n>1的時(shí)候,每一個(gè)輸出,都可以看作成為九宮格。
    • 接著我們可以注意一下每?jī)蓚€(gè)X之間的空格,就可以發(fā)現(xiàn)一定的規(guī)律。

    代碼:

    #include <bits/stdc++.h> using namespace std; int a[1010][1010],n,m,i,j; int power(int a,int b) {int ans=1;while(b){if (b&1)ans*=a;a*=a;b>>=1;}return ans; } void dg(int n,int x,int y) {if (n==1){a[x][y]=1;return ;}int len=power(3,n-2);//枚舉len的長(zhǎng)度,也就是枚舉兩個(gè)X之間的空格數(shù)dg(n-1,x,y);//左上dg(n-1,x+2*len,y);//右上dg(n-1,x+len,y+len);//中間dg(n-1,x,y+2*len);//左下dg(n-1,x+2*len,y+2*len);//右下 } int main() {while(cin>>n && n!=-1){memset(a,0,sizeof(a));dg(n,1,1);for(int i=1;i<=power(3,n-1);i++){for(int j=1;j<=power(3,n-1);j++)if (a[i][j])cout<<'X';elsecout<<' ';cout<<endl;}cout<<"-"<<endl;}return 0; }

    分治

    平面最近點(diǎn)對(duì)

    題目鏈接

    解題思路:
    詳細(xì)的題解

    代碼:

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> // 計(jì)算距離時(shí)需要用到 sqrt 函數(shù)using namespace std;const int N = 200005; const double INF = 1e15; const double eps = 1e-6;int n; double mind; struct point // 結(jié)構(gòu)體存所有點(diǎn) {double x, y; // 存每個(gè)點(diǎn)的坐標(biāo)bool type; // 存每個(gè)點(diǎn)的類型bool operator < (const point &t) const // 用于將所有點(diǎn)按 x 坐標(biāo)從小到大排序{return x < t.x;} } points[N], tmp[N]; // points 存輸入的每個(gè)點(diǎn),tmp 存分治時(shí)對(duì)于每個(gè)點(diǎn)要處理的點(diǎn)double get_dist(point a, point b) // 返回點(diǎn) a 和點(diǎn) b 的直徑距離 {if (a.type == b.type) return mind ; // 如果這兩個(gè)點(diǎn)的類型不同,返回當(dāng)前最優(yōu)答案即可。double dx = a.x - b.x, dy = a.y - b.y; // 計(jì)算出這兩個(gè)點(diǎn)橫縱坐標(biāo)的差值return sqrt(dx * dx + dy * dy); // 返回這兩個(gè)點(diǎn)的平面距離 }double dfs(int l, int r) {if (l == r) return INF ; // 如果剩下區(qū)域只有一個(gè)點(diǎn),那么為了避免更新答案,返回正無(wú)窮int mid = l + r >> 1; // 找到剩下區(qū)域內(nèi)中間的點(diǎn)的位置。double mid_x = points[mid].x; // 取出該點(diǎn)的 x 坐標(biāo),與該坐標(biāo)距離超過(guò) ans 的點(diǎn)不計(jì)入考慮。double ans = min(dfs(l, mid), dfs(mid + 1, r)); // 分治計(jì)算出上述未被更新的 ans// 先將 points 中的 [l, mid] 和 [mid + 1, r] 兩段進(jìn)行按 y 軸坐標(biāo)進(jìn)行按序歸并// 注意這里一定要?dú)w并,后面對(duì)于每個(gè)點(diǎn)我們才能快速找出對(duì)應(yīng)的(至多) 6 個(gè)點(diǎn),以保證總時(shí)間復(fù)雜度是 O(n log n)int i = l, j = mid + 1, cnt = 0;while (i <= mid && j <= r)if (points[i].y < points[j].y) tmp[cnt ++ ] = points[i ++ ];else tmp[cnt ++ ] = points[j ++ ];while (i <= mid) tmp[cnt ++ ] = points[i ++ ];while (j <= r) tmp[cnt ++ ] = points[j ++ ];for (i = l; i <= r; i ++ ) points[i] = tmp[i - l];// 找到所有在 [mid_x - ans, mid_x + ans] 中的點(diǎn),存入 tmpcnt = 0;for (i = l; i <= r; i ++ )if (points[i].x >= mid_x - ans && points[i].x <= mid_x + ans) // 如果說(shuō)該點(diǎn)距離 mid_x 的距離小于 ans,那么需要考慮該點(diǎn)tmp[cnt ++ ] = points[i];// 下面第二層循環(huán)中,有 tmp[i].y - tmp[j].y <= ans 這個(gè)判斷,才能保證我們對(duì)于每個(gè)點(diǎn)最多只考慮六個(gè)點(diǎn)// 這樣在每層遞歸中,就可以保證時(shí)間復(fù)雜度是線性的,否則時(shí)間復(fù)雜度是平方級(jí)別的for (i = 0; i < cnt; i ++ ) // 處理所有 tmp 中的點(diǎn)for (j = i - 1; ~j && tmp[i].y - tmp[j].y + eps <= ans; j -- )ans = min(ans, get_dist(tmp[i], tmp[j])); // 更新 ansmind = min(mind, ans);return ans; }int main() {int T;scanf("%d", &T);while (T -- ){scanf("%d", &n);for (int i = 0; i < n; i ++ ){scanf("%lf %lf", &points[i].x, &points[i].y); // 輸入所有核電站的坐標(biāo)points[i].type = false; // 核電站的 type 制成 false}for (int i = n; i < n << 1; i ++ ){scanf("%lf %lf", &points[i].x, &points[i].y); // 讀入所有特工的坐標(biāo)points[i].type = true; // 特工的 type 制成 true}mind = get_dist(points[0], points[(n << 1) - 1]);sort(points, points + (n << 1)); // 將所有點(diǎn)按 x 坐標(biāo)排序printf("%.3lf\n", dfs(0, (n << 1) - 1)); // 分治函數(shù)的返回值即為答案}return 0; }

    二分

    防線

    題目鏈接

    題目簡(jiǎn)譯:給定n個(gè)等差數(shù)列,每個(gè)等差數(shù)列的起點(diǎn)為s,終點(diǎn)為e,差為d。整個(gè)序列中至多有一個(gè)位置所占數(shù)字是奇數(shù)。判斷奇數(shù)位是否存在,如果不存在輸出"There’s no weakness.",如果存在輸出位置與大小。

    詳細(xì)題解

    個(gè)人理解:

    我們是利用前綴和的思想找到個(gè)數(shù)為奇數(shù)的位置,因?yàn)槲覀冎酪粋€(gè)序列里邊有一個(gè)奇數(shù),其余全是偶數(shù)那么其和一定為奇數(shù),那么我們找的位置滿足其前邊的和為偶數(shù),其后邊的和為奇數(shù),這就符合了二分答案意思了。

    技巧:

    • 因?yàn)槲覀兪嵌治恢?#xff0c;假設(shè)該位置為x,那么我們需要求出從開始節(jié)點(diǎn)到這個(gè)區(qū)間中點(diǎn)的數(shù)量。有公式此區(qū)間包含此數(shù)列的個(gè)數(shù)是?(min(e,x)?s)/d?+1。此區(qū)間包含此數(shù)列的個(gè)數(shù)是?(min(e,x)?s)/d?+1。區(qū)數(shù)個(gè)數(shù)?(min(e,x)?s)/d?+1

    代碼:

    #include<stdio.h> #include<algorithm> #include<iostream> using namespace std;typedef long long ll ; const int N = 2E5 + 10; int n; struct seg{ll s,e,d; }segs[N];ll get_sum(ll x){ll ans = 0;for(int i = 0;i< n;++i)if(segs[i].s <= x)ans += (min(segs[i].e,x) - segs[i].s)/ segs[i].d + 1;return ans; }int main(){int T ;scanf("%d",&T);while(T--){scanf("%d",&n);ll l = 0 , r = 0;for(int i = 0;i<n;++i){ scanf("%d%d%d",&segs[i].s,&segs[i].e,&segs[i].d);r = max(r,segs[i].e);}while(l < r){int mid = (l + r) >> 1;// 如果為奇數(shù)那么該位置在前一個(gè)區(qū)間上if(get_sum(mid) & 1) r = mid;else l = mid + 1;} auto ans = get_sum(l) - get_sum(l - 1);if(ans % 2 )printf("%d %lld\n",r,ans);else puts("There's no weakness.");}return 0;}

    趕牛入圈

    題目鏈接

    解題思路:

    首先為為什么可以二分答案呢(矩形的邊長(zhǎng)),因?yàn)槿绻凶顑?yōu)解的話,那么在這個(gè)最優(yōu)解的左邊是不符合題意的,右邊是符合題意的但不是最優(yōu)的。
    那為什么要離散化呢?因?yàn)槿绻覀儽┝z測(cè)一個(gè)邊長(zhǎng)是否合法的話是可以通過(guò)二維前綴和枚舉每一個(gè)坐標(biāo)來(lái)檢測(cè)的,但這題坐標(biāo)個(gè)數(shù)最大為10000,這樣的話最壞是n方的。而題目告訴我們N 單位,其中N < 500.也就是說(shuō)很都坐標(biāo)都是重復(fù)的因此我們可以對(duì)其進(jìn)行離散化。

    離散化

    1、數(shù)組

    //離散化 void discreate(){sort(a+1,a+1+n);for(int i = 1;i<=n;++i){if(i == 1 || a[i] != a[i-1])b[m++] = a[i];} } // 查詢 int query(int x){return lower_bound(b+1,b+1+m,x) - b; }

    2.vector

    //離散化 void discreate(){sort(numbers.begin(),numbers.end());numbers.erase(unique(numbers.begin(),numbers.end()) , numbers.end()); } // 查詢 int query(int x){return lower_bound(numbers.begin(),numbers.end(),x) - numbers.begin(); }


    代碼:

    #include<stdio.h> #include<algorithm> #include<vector>using namespace std; typedef pair<int,int> PII; const int N = 1110;int n,C; PII points[N]; int sum[N][N]; vector<int> numbers;int get(int x){return lower_bound(numbers.begin(),numbers.end(),x) - numbers.begin(); }// 邊長(zhǎng)為len bool check(int len){int size = numbers.size();//在離散之后就變成了一維直線上的包含問題了,for(int x1 = 0 ,x2 = 1 ; x2 < size;++x2){while(numbers[x2] - numbers[x1+1] + 1 > len) x1++;for(int y1 = 0 , y2 = 1 ; y2 < size; ++y2){while(numbers[y2] - numbers[y1+1] +1 > len) y1 ++ ;if((sum[x2][y2] - sum[x1][y2] - sum[x2][y1] + sum[x1][y1]) >= C)return true;}}return false; }int main(){scanf("%d%d",&C,&n);numbers.push_back(0);for(int i = 0 , x, y ;i < n ;++i){scanf("%d%d",&x,&y);points[i] = {x,y};numbers.push_back(x);numbers.push_back(y);}sort(numbers.begin(),numbers.end());numbers.erase(unique(numbers.begin(),numbers.end()) , numbers.end());// 初始化前綴和// 相當(dāng)于如果x,y 坐標(biāo)重復(fù)的話 sum[x][y] 會(huì)得到累加for(int i = 0 ;i<n;++i){int x = get(points[i].first) , y = get(points[i].second);sum[x][y] ++;}for(int i = 1;i<numbers.size();++i)for(int j = 1;j<numbers.size();++j)sum[i][j] += sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];// 二分答案int l = 1 , r = 10000;while( l < r){int mid = l + r >> 1;if(check(mid)) r = mid;else l = mid + 1;}printf("%d\n",r);return 0; }

    中位數(shù)

    糖果傳遞【環(huán)形紙牌均分問題】

    題目鏈接

    解題思路:


    由上面的式子我們就可以將問題轉(zhuǎn)化為給定數(shù)軸上的n個(gè)點(diǎn),找出一個(gè)到他們的距離之和盡量小的點(diǎn),而這個(gè)點(diǎn)就是這些數(shù)中的中位數(shù)。重要的是如何得到c[i]數(shù)組,我們由上圖得到 c[1] = -b + a1 ,c[2] = -2b + a1 + a2 = c[1] + a2 - b,… , 我們就可以通過(guò)迭代一遍算出 c了。同時(shí)要注意的是 c[n] = 0 ;

    代碼:

    #include<stdio.h> #include<algorithm> #include<cmath> using namespace std; typedef long long ll ; const int N = 1e6 + 10; int a[N], n ; ll c[N], sum,avg;int main(){sum = 0;scanf("%d",&n);for(int i = 0; i< n;++i){scanf("%d",&a[i]);sum += a[i];}avg = sum / n;// c[1] = -b + a1 ,c[2] = -2b + a1 + a2 = c[1] + a2 - bfor(int i = 1 ;i<= n;++i)c[i] = c[i-1] + a[i] - avg;c[n] = 0; // 最后一項(xiàng)特判以下為是為0sort(c+1,c+n+1);long long ans = 0;for(int i = 1;i<=n;++i)ans += abs (c[i] - c[(n>>1) +1]);printf("%lld\n",ans);return 0; }

    士兵

    題目鏈接

    解題思路:

    該問題是求x與y移動(dòng)距離之和最小,而x與y是獨(dú)立的。對(duì)于y軸我們可以看成是貨倉(cāng)問題了,只要排個(gè)序累加每一個(gè)點(diǎn)到中位數(shù)的距離即可。對(duì)于x軸因?yàn)橐WCx坐標(biāo)相鄰且不重復(fù),那么對(duì)于最優(yōu)的次數(shù)有一個(gè)性質(zhì)是x坐標(biāo)的相對(duì)位置不會(huì)改變,即你在我之前的,在移動(dòng)后你應(yīng)該任然在我前邊,
    設(shè)最左邊的士兵走到x1=a處,那么由題意,第2個(gè)走到x2=a+1處,第i個(gè)走到xi=a+i?1處.那么,第i個(gè)士兵要走|xi?(a+i?1)|=|xi?(i?1)?a||xi?(a+i?1)|=|xi?(i?1)?a|單位距離.
    將xi?(i?1)看成一個(gè)整體,問題就又轉(zhuǎn)化為”貨倉(cāng)選址”問題了,排序,取中位數(shù)即可.


    這里a是未知的x是已知的。

    注意:

    如果下標(biāo)從0開始,那么中位數(shù)對(duì)應(yīng)的下標(biāo)應(yīng)該是 n/2 ,當(dāng)下標(biāo)從1開始,則是(n+1) / 2.

    代碼;

    #include<stdio.h> #include<algorithm> #include<cmath> using namespace std; typedef long long ll;const int N = 1E4 + 10;int x[N] , y[N]; int n;int main(){scanf("%d",&n);for(int i = 0;i<n;++i)scanf("%d%d",&x[i],&y[i]);// 要先對(duì)x坐標(biāo)排個(gè)序sort(x,x+n);for(int i = 0;i<n;++i)x[i] -= i;sort(x,x+n),sort(y,y+n);ll ans = 0;for(int i = 0;i<n;++i){ans += abs( y[i] - y[n /2]);ans += abs( x[i] - x[n/2]);}printf("%lld\n",ans);return 0; }

    貪心

    耍雜技的牛

    題目鏈接

    解題思路
    我們考慮相鄰的第 i 頭牛 與第 i+1 頭牛

    其他牛的危險(xiǎn)值顯然不變,所以分析交換前后這兩頭牛中最大的危險(xiǎn)值即可。

    我們?yōu)榱俗尳粨Q前最優(yōu),那么要有交換前的最大值 小于 交換后的最大值。明顯wi?si+1>?si+1w_i - s_{i+1} > -s_{i+1}wi??si+1?>?si+1?,所以我們只要wi?si+1<wi+1?siw_i - s_{i+1} <w_{i+1} -s_{i}wi??si+1?<wi+1??si?既可以,整理一下得到wi+si<wi+1?si+1w_i + s_{i} < w_{i+1} -s_{i+1}wi?+si?<wi+1??si+1?

    代碼:

    #include<stdio.h> #include<algorithm>using namespace std;typedef long long ll;const int N = 5E4+10;int n; struct cow{ll w,s; }cows[N];//從小到大排序,小的放到頂部 bool cmp(cow a,cow b){return a.w + a.s < b.w + b.s; }int main(){scanf("%d",&n);for(int i = 0;i<n;++i)scanf("%lld%lld",&cows[i].w,&cows[i].s);sort(cows,cows + n,cmp);ll sum = 0 , ans =- 98765421;for(int i = 0;i<n;++i){ll temp = sum - cows[i].s;ans = max(ans,temp);sum += cows[i].w;}printf("%lld\n",ans);return 0; }

    任務(wù)

    題目鏈接

    解題四路:

    我門發(fā)現(xiàn)這題 x 是主導(dǎo)收益的,所依只要x大我們就不用考慮y,因此我們以x為第一關(guān)鍵字,y為第二關(guān)鍵字進(jìn)行降序排列(升序也可以,遍歷的時(shí)候反著遍歷即可)。將x,y放到坐標(biāo)軸上,我們可以知道能滿足任務(wù)的機(jī)器一定在任務(wù)點(diǎn)的右上方,然后我們考慮對(duì)于x大于任務(wù)的機(jī)器,我們把y從小到大排序,從中選出一個(gè)最次的不過(guò)能符合的機(jī)器進(jìn)行操作。

    代碼:

    #include<stdio.h> #include<set> #include<algorithm>using namespace std;typedef pair<int ,int >PII; typedef long long ll; const int N = 1E5 + 10; int n,m; PII machs[N],tasks[N];int main(){while(~scanf("%d%d",&n,&m)){for(int i = 0;i<n;++i)scanf("%d%d",&machs[i].first,&machs[i].second);for(int i = 0;i<m;++i)scanf("%d%d",&tasks[i].first,&tasks[i].second);//PII 默認(rèn)以第一個(gè)為第一關(guān)鍵字,第二個(gè)為第二關(guān)鍵字,升序排列sort(machs,machs + n);sort(tasks,tasks + m);multiset<int>ys;ll cnt = 0 ,res = 0;// 所以是從后往前遍歷for(int i = m-1,j = n-1;i>=0;i--){int x = tasks[i].first , y = tasks[i].second;// 將符合條件的機(jī)器加進(jìn)去,因?yàn)閟et會(huì)對(duì)里邊的元素默認(rèn) 從小到大排序while(j>= 0 && machs[j].first >= x) ys.insert( machs[j--].second);auto it = ys.lower_bound(y); // 找到一個(gè)符合的bug是最次的if(it != ys.end()){cnt ++ ;res += 500 * x + 2* y;ys.erase(it);}}printf("%lld %lld\n",cnt,res);}return 0; }

    前綴和

    最大子矩陣的和(二維列前綴和)

    題目鏈接

    解題思路:

    我們回想一下一維的時(shí)候我們求最大連續(xù)區(qū)間和的做法,我們的做法是動(dòng)態(tài)規(guī)劃,其中 dp[i]的含義是i的最大連續(xù)區(qū)間的和,dp[i]=mix(0,dp[i?1])+a[i]dp[i] 的含義是i的最大連續(xù)區(qū)間的和 ,dp[i] = mix(0,dp[i-1]) + a[i]dp[i]i續(xù)區(qū)dp[i]=mix(0,dp[i?1])+a[i] 因此在這里我們可以采用這種思路將這題變?yōu)橐粋€(gè) O(n3)O(n^3)On3的做法。如下圖

    所以思路是兩重循環(huán)遍歷矩陣的上下邊界,注意可以是直線,然后將這個(gè)邊界的所有列的和看成一個(gè)數(shù)就變成了最大連續(xù)區(qū)間和。而快速求出所有列的和我們可以利用前綴和優(yōu)化就可以了,

    代碼:

    #include<stdio.h> #include<stdlib.h> #include<algorithm> #include<limits.h> using namespace std; const int N = 110;int g[N][N]; int n;int main(){scanf("%d",&n);for(int i = 1 ;i<= n ;++i)for(int j = 1;j<=n;++j){scanf("%d",&g[i][j]);g[i][j] += g[i-1][j]; //每一列進(jìn)行前綴和}int res = INT_MIN;for(int i = 1;i<=n;++i)for(int j = i;j<=n;++j){int last = 0;for(int k = 1;k<=n;++k){// g[j][k] - g[i-1][k] 就是 第k列 i ~j 行的所有數(shù)的和last = max(0,last) + g[j][k] - g[i-1][k];res = max(res,last);}}printf("%d\n",res);return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的基本算法总结篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。