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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Hihocoder - offer编程练习赛93 套题题解】交错01串(贪心,暴力)方格矩阵高度(模拟)数对(STLmultiset)修整土地(网络流)

發(fā)布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Hihocoder - offer编程练习赛93 套题题解】交错01串(贪心,暴力)方格矩阵高度(模拟)数对(STLmultiset)修整土地(网络流) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

A:

題干:

時間限制:10000ms

單點時限:1000ms

內(nèi)存限制:256MB

描述

小Hi要將一個01串S傳輸給小Ho,由于S非常長,所以小Hi決定用長度為N的2個數(shù)組A = [A1, A2, ..., AN]和B = [B1, B2, ..., BN]表示S。 ?

具體來講,是指S由N段連續(xù)的字符串組成,其中第i段包含Ai個Bi。其中Bi可能是0或1。 ?

例如 A = [1, 2, 3, 4], B = [1, 0, 0, 1]表示S = "1000001111"。 ?

現(xiàn)在小Ho想把S變成一個01交錯的字符串。請你幫他計算他最少要改變S中多少個字符才能達成?

輸入

第一行包含一個整數(shù)N。 ?

第二行包含N個整數(shù),A1, A2, A3, ... AN。 ?

第三行包含N個整數(shù),B1, B2, B3, ... BN。 ?

1 <= N <= 100000 ?

1 <= Ai <= 100000 ?

0 <= Bi <= 1

輸出

一個整數(shù)代表答案

樣例輸入

4 1 2 3 4 1 0 0 1

樣例輸出

4

解題報告:

?

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; int a[MAX],b[MAX]; int main() {int n;cin>>n;ll sum = 0;for(int i = 1; i<=n; i++) scanf("%d",a+i),sum += a[i]/2;for(int i = 1; i<=n; i++) scanf("%d",b+i);//開頭是1 ll ans1 = 0;bool sd = 1;for(int i = 1; i<=n; i++) {if(b[i] == sd) {ans1 += a[i]/2;if(a[i]&1) sd = !sd;}else {ans1 += (a[i]+1)/2;if(a[i]&1) sd = !sd; }}ll ans2 = 0;sd = 0;for(int i = 1; i<=n; i++) {if(b[i] == sd) {ans2 += a[i]/2;if(a[i]&1) sd = !sd;}else {ans2 += (a[i]+1)/2;if(a[i]&1) sd = !sd; }} printf("%lld\n",min(ans1,ans2));return 0 ;}

B:

題干:

時間限制:10000ms

單點時限:1000ms

內(nèi)存限制:256MB

描述

小Hi有NxM的方格矩陣,每個方格的高度是Hij。例如如下是2x3的方格矩陣和每個方格的高度:

--> 1 3 4左 2 5 3視 ^圖 |前視圖

左邊看過去,可以得到方格矩陣的左視圖L = [L1 ... LN];從前邊看過去,可以得到方格矩陣的前視圖F = [F1 ... FM]。 ?

例如上例中L = [4, 5], F = [2, 5, 4]。

現(xiàn)在小Ho不知道每個方格的高度,只知道這些方格的左視圖和前視圖。他發(fā)現(xiàn)只知道左視圖和前視圖并不一定能唯一確定一個方格矩陣。

例如

2 4 4 2 5 4

的左視圖和前視圖也是L = [4, 5]和F = [2, 5, 4]。 ?

于是小Ho想知道,對于所有可能的方格矩陣,格子高度之和最大是多少。

輸入

第一行包含兩個整數(shù)N和M。 ?

第二行包含N個整數(shù)L1, L2, ... LN,代表左視圖。 ?

第三行包含M個整數(shù)F1, F2, ... FM,代表前視圖。

1 <= N, M <= 1000 ?

1 <= Li, Fi <= 1000

輸出

一個整數(shù)代表答案

樣例輸入

2 3 4 5 2 5 4

樣例輸出

21

解題報告:

N*M暴力跑就行了。枚舉每一個看他可以達到的最大值。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; int n,m; int h[MAX],q[MAX]; int main() {ll ans = 0;cin>>n>>m;for(int i = 1; i<=n; i++) cin>>h[i];for(int i = 1; i<=m; i++) cin>>q[i];for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {ans += min(h[i],q[j]);}}cout <<ans;return 0 ;}

C:

題干:

時間限制:10000ms

單點時限:1000ms

內(nèi)存限制:256MB

描述

給定N個整數(shù)A1, A2, ... AN。現(xiàn)在小Ho可以任意從中取出兩個整數(shù)X,Y湊成一個數(shù)對(X, Y),只要滿足Y = 2X。 ?

如果每個Ai最多被取出一次,請你幫小Ho計算他最多能湊出多少個數(shù)對?

輸入

第一行包含一個整數(shù)N。 ?

第二行包含N個整數(shù)A1, A2, ... AN。 ?

1 <= N <= 100000 ?

1 <= Ai <= 100000

輸出

一個整數(shù)代表答案

樣例輸入

5 1 2 4 8 16

樣例輸出

2

解題報告:

? ?這題數(shù)據(jù)范圍沒有加滿,所以可以用數(shù)組來計數(shù)(AC代碼1),這題Ai加到1e18也可以做(AC代碼2)。

AC代碼1:

#include<bits/stdc++.h> using namespace std; typedef long long ll; ll ans=0; int n; int a[100005]; int cnt[100005]; int main() {scanf("%d",&n);for(int i=0; i<n; i++)scanf("%d",&a[i]),cnt[a[i]]++;sort(a,a+n);for(int i=0; i<n; i++) {if(a[i]%2==0&&cnt[a[i]/2]) {ans++;cnt[a[i]/2]--;cnt[a[i]]--;}}cout<<ans;return 0; }

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; multiset<int> ms; int a[MAX],n; int main() {int ans = 0;cin>>n;for(int i = 1; i<=n; i++) {cin>>a[i];ms.insert(a[i]);}auto it = ms.begin();for(int i = 1; i<=n/2; i++) { while(ms.find((*it)*2) == ms.end() && it != ms.end()) ++it;if(it != ms.end()) {auto itt = ms.find((*it)*2);ans++;ms.erase(itt);itt = it;++it;ms.erase(itt);}else break;}cout <<ans;return 0 ;}

D:

題干:

時間限制:20000ms

單點時限:2000ms

內(nèi)存限制:256MB

描述

H市的土地如下圖所示,呈現(xiàn)NxM塊區(qū)域,每一塊區(qū)域都有自己的高度Hij。

+---+---+---+---+---+---+|H11|H12|H13|H14|...|H1M|+---+---+---+---+---+---+|H21|H22|H23|H24|...|H2M|+---+---+---+---+---+---+. . . . . . .|HN1|HN2|HN3|HN4|...|HNM|+---+---+---+---+---+---+

為了使以后的城市交通比較便利,H市決定將土地進行平整,使得所有的區(qū)域高度相等。已知將1個單位的土地移動到相鄰的區(qū)域需要花費1的費用,同時當前區(qū)域的高度降低1,接收土地的區(qū)域高度增加1。那么將所有的區(qū)域調(diào)整到相同的高度所需的最小費用是多少呢?

輸入

第一行包含兩個整數(shù)N和M。 ?

以下N行包含一個NxM的矩陣H。

0 <= Hij <= 1000

1 <= N, M <= 50

輸出

一個整數(shù)代表答案

樣例輸入

2 2 3 4 6 7

樣例輸出

4

解題報告:

? ?一眼網(wǎng)絡流。先計算出最終平衡時所有點的高度值sum(可以計算出,相當于已知)。建圖:建一個起點連向所有可以高度減少的點,流量是h[i][j]-sum(因為他必須減少),費用是0;新建一個匯點,高度需要增加的點連向匯點,流量是sum-h[i][j],費用是0,那么這樣建圖首先保證了源點流出的流量==匯點流入的流量,這也就保證了流量不會丟失,也就是最大流就是這么大,所以滿足了我們需要求最小費用,的要求。相當于是我通過建圖,首先固定了最大流(因為新建的源點到新建的匯點,最大流肯定就是min(源點連出的所有的邊的流量之和,匯點流入的所有的邊的流量之和),而這兩者相同,所以最大流已經(jīng)確定了,就是源點連出的所有邊的流量之和,也就是源點流出的流量),然后跑模板去求最小費用就行了。

不過這題他數(shù)據(jù)錯了你敢信,,,給的范圍根本不是50*50的,,而且遠大于這個,,怪不得一直RE。。。

另一種建圖方式:起點到每一個點都有一個流量h[i][j]費用0的邊,每個點都到終點有一個流量sum費用0的邊,然后每個點向四周連邊。合法性的證明參考上一種建圖方式。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long using namespace std;const int MAXN = 70000; const int MAXM = 100005; const int INF = 0x3f3f3f3f; struct Edge {int to,next,cap,flow,cost; } edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int n,m; int N;//節(jié)點總個數(shù),節(jié)點編號從 0 ~ N-1 void init(int n) {N = n;tol = 0;memset(head, -1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) {edge[tol].to = v;edge[tol].cap = cap;edge[tol].cost = cost;edge[tol].flow = 0;edge[tol].next = head[u];head[u] = tol++;edge[tol].to = u;edge[tol].cap = 0;edge[tol].cost = -cost;edge[tol].flow = 0;edge[tol].next = head[v];head[v] = tol++; } bool spfa(int s,int t) {queue<int>q;for(int i = 0; i <= N; i++) {dis[i] = INF;vis[i] = false;pre[i] = -1;}dis[s] = 0;vis[s] = true;q.push(s);while(!q.empty()) {int u = q.front();q.pop();vis[u] = false;for(int i = head[u]; i !=-1; i = edge[i].next) {int v = edge[i].to;if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) {dis[v] = dis[u] + edge[i].cost;pre[v] = i;if(!vis[v]) {vis[v] = true;q.push(v);}}}}if(pre[t] ==-1)return false;else return true;} //返回的是最大流,cost 存的是最小費用 int minCostMaxflow(int s,int t,int &cost) {int flow = 0;cost = 0;while(spfa(s,t)) {int Min = INF;for(int i = pre[t]; i !=-1; i = pre[edge[i^1].to]) {if(Min > edge[i].cap-edge[i].flow)Min = edge[i].cap-edge[i].flow;}for(int i = pre[t]; i !=-1; i = pre[edge[i^1].to]) {edge[i].flow += Min;edge[i^1].flow-= Min;cost += edge[i].cost * Min;}flow += Min;}return flow; } int nx[]={0,1,0,-1}; int ny[]={1,0,-1,0}; int id(int i,int j) {return (i-1)*m+j; } int h[555][555]; int main() {while(~scanf("%d%d",&n,&m)) {init(n*m+22);int st=0,ed=n*m+1,sum = 0; for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {scanf("%d",&h[i][j]);sum += h[i][j];}}sum /= (n*m);for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(h[i][j] > sum) addedge(st,id(i,j),h[i][j] - sum,0);else if(h[i][j] < sum) addedge(id(i,j),ed, sum - h[i][j],0);}}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {for(int k = 0; k<4; k++) {int tx = i + nx[k];int ty = j + ny[k];if(tx<1||tx>n||ty<1||ty>m) continue;addedge(id(i,j),id(tx,ty),INF,1);} }} int cost;int ans = minCostMaxflow(st,ed,cost);printf("%d\n",cost);}return 0 ; }

?

總結

以上是生活随笔為你收集整理的【Hihocoder - offer编程练习赛93 套题题解】交错01串(贪心,暴力)方格矩阵高度(模拟)数对(STLmultiset)修整土地(网络流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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