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

A:

题干:

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

小Hi要将一个01串S传输给小Ho,由于S非常长,所以小Hi决定用长度为N的2个数组A = [A1, A2, ..., AN]和B = [B1, B2, ..., BN]表示S。  

具体来讲,是指S由N段连续的字符串组成,其中第i段包含Ai个Bi。其中Bi可能是0或1。  

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

现在小Ho想把S变成一个01交错的字符串。请你帮他计算他最少要改变S中多少个字符才能达成?

输入

第一行包含一个整数N。  

第二行包含N个整数,A1, A2, A3, ... AN。  

第三行包含N个整数,B1, B2, B3, ... BN。  

1 <= N <= 100000  

1 <= Ai <= 100000  

0 <= Bi <= 1

输出

一个整数代表答案

样例输入

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

内存限制:256MB

描述

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

-->    1 3 4左    2 5 3视      ^图      |前视图

左边看过去,可以得到方格矩阵的左视图L = [L1 ... LN];从前边看过去,可以得到方格矩阵的前视图F = [F1 ... FM]。  

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

现在小Ho不知道每个方格的高度,只知道这些方格的左视图和前视图。他发现只知道左视图和前视图并不一定能唯一确定一个方格矩阵。

例如

2 4 4
2 5 4

的左视图和前视图也是L = [4, 5]和F = [2, 5, 4]。  

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

输入

第一行包含两个整数N和M。  

第二行包含N个整数L1, L2, ... LN,代表左视图。  

第三行包含M个整数F1, F2, ... FM,代表前视图。

1 <= N, M <= 1000  

1 <= Li, Fi <= 1000

输出

一个整数代表答案

样例输入

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

内存限制:256MB

描述

给定N个整数A1, A2, ... AN。现在小Ho可以任意从中取出两个整数X,Y凑成一个数对(X, Y),只要满足Y = 2X。  

如果每个Ai最多被取出一次,请你帮小Ho计算他最多能凑出多少个数对?

输入

第一行包含一个整数N。  

第二行包含N个整数A1, A2, ... AN。  

1 <= N <= 100000  

1 <= Ai <= 100000

输出

一个整数代表答案

样例输入

5  
1 2 4 8 16

样例输出

2

解题报告:

   这题数据范围没有加满,所以可以用数组来计数(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

内存限制:256MB

描述

H市的土地如下图所示,呈现NxM块区域,每一块区域都有自己的高度Hij。

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

为了使以后的城市交通比较便利,H市决定将土地进行平整,使得所有的区域高度相等。已知将1个单位的土地移动到相邻的区域需要花费1的费用,同时当前区域的高度降低1,接收土地的区域高度增加1。那么将所有的区域调整到相同的高度所需的最小费用是多少呢?

输入

第一行包含两个整数N和M。  

以下N行包含一个NxM的矩阵H。

0 <= Hij <= 1000

1 <= N, M <= 50

输出

一个整数代表答案

样例输入

2 2
3 4
6 7

样例输出

4

解题报告:

   一眼网络流。先计算出最终平衡时所有点的高度值sum(可以计算出,相当于已知)。建图:建一个起点连向所有可以高度减少的点,流量是h[i][j]-sum(因为他必须减少),费用是0;新建一个汇点,高度需要增加的点连向汇点,流量是sum-h[i][j],费用是0,那么这样建图首先保证了源点流出的流量==汇点流入的流量,这也就保证了流量不会丢失,也就是最大流就是这么大,所以满足了我们需要求最小费用,的要求。相当于是我通过建图,首先固定了最大流(因为新建的源点到新建的汇点,最大流肯定就是min(源点连出的所有的边的流量之和,汇点流入的所有的边的流量之和),而这两者相同,所以最大流已经确定了,就是源点连出的所有边的流量之和,也就是源点流出的流量),然后跑模板去求最小费用就行了。

不过这题他数据错了你敢信,,,给的范围根本不是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;//节点总个数,节点编号从 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 ;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440713.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux防火墙配置连接atlas,ATLAS在ubuntu下的安装使用

1, 根据atlas的安装文档, 首先要switch off cpu throttling.在Ubuntu系统上要首先安装cpufrequtils和cpufreqd这两个包, 也许还要安装powernowd包,然后执行sudo /usr/bin/cpufreq-selector –g. 不过幸运的是, 我在server上安装的时候发现cputhrottling已经disable了(否则在con…

【CodeForces - 545 ABCDE套题训练题解】贪心, 构造,模拟,dp,最短路树(Dijkstra+变形)

A&#xff1a; 题干&#xff1a; Input The first line contains integer n (1 ≤ n ≤ 100) — the number of cars. Each of the next n lines contains n space-separated integers that determine matrix A. It is guaranteed that on the main diagonal there ar…

linux搜索pdf文件,桌面应用|如何使用 pdfgrep 从终端搜索 PDF 文件

诸如 grep 和 ack-grep 之类的命令行工具对于搜索匹配指定正则表达式的纯文本非常有用。但是你有没有试过使用这些工具在 PDF 中搜索&#xff1f;不要这么做&#xff01;由于这些工具无法读取PDF文件&#xff0c;因此你不会得到任何结果。它们只能读取纯文本文件。顾名思义&…

【CodeForces - 546C 】Soldier and Cards (模拟)

题干&#xff1a; Two bored soldiers are playing card war. Their card deck consists of exactly n cards, numbered from 1 to n, all values are different. They divide cards between them in some manner, its possible that they have different number of cards. Th…

linux wifi 蓝牙冲突,linux 下 无线 wifi 蓝牙 无法启用

linux 下 无线 wifi 蓝牙 无法启用装了Debian squeeze 后发现无线不能打开首先想到的是装驱动于是在wiki.debian.org上查了下以重新装了下驱动#aptitude install firmware-b43-installler#modprobe b43# iwconfiglo no wireless extensions.eth0 no wireless exten…

Linux中wait接口用于延时,linux2.6驱动编写参考

1、 使用新的入口必须包含 module_init(your_init_func);module_exit(your_exit_func);老版本&#xff1a;int init_module(void);void cleanup_module(voi);2.4中两种都可以用&#xff0c;对如后面的入口函数不必要显示包含任何头文件。2、 GPLMODULE_LICENSE("Dual BSD/…

【51nod - 1108】距离之和最小 V2(曼哈顿距离,中位数性质)

题干&#xff1a; 三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小&#xff0c;输出这个最小的距离之和。 点(x1,y1,z1)到(x2,y2,z2)的曼哈顿距离就是|x1-x2| |y1-y2| |z1-z2|。即3维坐标差的绝对值之和。 收起 输入 第1行&#xff1a;点的数量N。(2 <…

Linux实验室阿里云证书,开发者云体验实验室

{"data":[{"title":"技术领域","data":[{"title":"全部","key":1,"children":[{"title":"程序语言","key":12,"children":[{"title":&qu…

【OpenJudge - noi - 7624】山区建小学(dp)

题干&#xff1a; 总时间限制: 1000ms 内存限制: 65536kB 描述 政府在某山区修建了一条道路&#xff0c;恰好穿越总共m个村庄的每个村庄一次&#xff0c;没有回路或交叉&#xff0c;任意两个村庄只能通过这条路来往。已知任意两个相邻的村庄之间的距离为di&#xff08;为…

nuc8i7beh安装linux随机重启,【图片】来分享一下我的NUC8I7BEH【intelnuc吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼测试来了&#xff0c;Linux 脚本&#xff0c;2G测试&#xff0c;操完这次以后休息俩礼拜。ssd随机读4kfio -filename./ran4K.log -direct1 -iodepth 1 -thread -rwrandread -ioenginepsync -bs4k -size2G -numjobs10 -runtime1000 …

【Codeforces - 找不到题号】三元环计数(bitset优化,压位)

题干&#xff1a; 给你一个二维字符矩阵&#xff0c;如果 ( i , j ) 为 表明 两点之间有一条有向边&#xff0c;为-表示没有边&#xff0c;那么你要找出所有的三元环的个数。顶点数N<1500。 解题报告&#xff1a; 考虑最暴力的方法&#xff0c;开个二维数组来存每两个顶点之…

自定义函数删除字母C语言,[编程入门]自定义函数之字符提取-题解(C语言代码)...

解题思路:输入一个字符串&#xff0c;调用函数&#xff0c;遍历字符串中每一个字符&#xff0c;看是否含有aeiou字符&#xff0c;若有&#xff0c;将其保存到另一个字符型数组中&#xff0c;在主函数中对得到的字符型数组进行排序&#xff0c;输出。注意事项:题目要求顺序输出元…

【Hihocoder - offer编程练习赛39 - D】前缀后缀查询(后缀字典树,哈希,思维)

题干&#xff1a; 时间限制:10000ms 单点时限:1000ms 内存限制:512MB 描述 给定一个包含N个单词的字典:{W1, W2, W3, ... WN}&#xff0c;其中第i个单词Wi有具有一个权值Vi。 现在小Hi要进行M次查询&#xff0c;每次查询包含一个前缀字符串Pi和一个后缀字符串Si。他希望…

c 语言 while break,26 C 语言中的break和continue - C 语言基础教程

循环语句很好用&#xff0c;但是如果循环进行到一般想要跳出循环或者结束循环怎么办&#xff1f;那么那你需要 break 和 continue 语句。1. break 和 continue 的使用语法1.1 or 循环中使用 break 和 continuebreakfor (控制循环的变量; 循环判断条件; 循环变量增减变化){语句1…

【牛客 - 21302】被3整除的子序列(线性dp)

题干&#xff1a; 给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除 答案对1e97取模 输入描述: 输入一个字符串&#xff0c;由数字构成&#xff0c;长度小于等于50 输出描述: 输出一个整数 示例1 输入 复制 132 输出 复制 3 示例2 输入 复制 …

c语言链表实现数组逆置,数组与链表等顺序表逆置

一)数组的逆置(1)算法#indclude#define N 8main(){int array[N] {100,90,80,70,60,50,50,40};int i,j,t;for(i0,jN-1;i{t array[i];array[i] array[j];array[j] t;}for(i0,iprintf("%d",qlist.data[i])}(2)时间复杂度由于只需循环N/2即可完成逆置,所以时…

linux系统get命令详解,Ubuntu Linux系统下apt-get命令详解

整理了Ubuntu Linux操作系统下apt-get命令的详细说明,分享给大家。常用的APT命令参数&#xff1a;apt-cache search package 搜索包apt-cache show package 获取包的相关信息&#xff0c;如说明、大小、版本等sudo apt-get install package 安装包sudo apt-get install package…

*【Hihocoder - offer编程练习赛94 - A】最短管道距离(中位数)

题干&#xff1a; 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在一张2D地图上有N座城市&#xff0c;坐标依次是(X1, Y1), (X2, Y2), ... (XN, YN)。 现在H国要修建一条平行于X轴的天然气主管道。这条管道非常长&#xff0c;可以认为是一条平行于X轴的直线。…

android开发百度地图坐标偏差,利用百度地图Android sdk高仿微信发送位置功能及遇到的问题...

接触了百度地图开发平台半个月了&#xff0c;这2天试着模仿了微信给好友发送位置功能&#xff0c;对百度地图的操作能力又上了一个台阶我在实现这个功能的时候&#xff0c;遇到一些困难&#xff0c;可能也是别人将会遇到的困难&#xff0c;特在此列出1、在微信发送功能中&#…

*【牛客 1 - A】矩阵(字符串hash)

题干&#xff1a; 给出一个n * m的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵中出现了至少两次。输出最大正方形的边长。 输入描述: 第一行两个整数n, m代表矩阵的长和宽&#xff1b; 接下来n行&#xff0c;每行m个字符&#xff08;小写字母&#xff…