您的位置:首页 > 其它

2018年全国多校算法寒假训练营练习比赛(第四场)(图论)

2018-02-11 18:28 861 查看
链接:https://www.nowcoder.net/acm/contest/76/A

来源:牛客网

随着海上运输石油泄漏的问题,一个新的有利可图的行业正在诞生,那就是撇油行业。如今,在墨西哥湾漂浮的大量石油,吸引了许多商人的目光。这些商人们有一种特殊的飞机,可以一瓢略过整个海面20米乘10米这么大的长方形。(上下相邻或者左右相邻的格子,不能斜着来)当然,这要求一瓢撇过去的全部是油,如果一瓢里面有油有水的话,那就毫无意义了,资源完全无法利用。现在,商人想要知道,在这片区域中,他可以最多得到多少瓢油。

地图是一个N×N的网络,每个格子表示10m×10m的正方形区域,每个区域都被标示上了是油还是水

输入描述:

测试输入包含多条测试数据

测试数据的第一行给出了测试数据的数目T(T<75)

每个测试样例都用数字N(N<50)来表示地图区域的大小,接下来N行,每行都有N个字符,其中符号’.’表示海面、符号’#’表示油面。

输出描述:

输出格式如下“Case X: M”(X从1开始),M是商人可以最多得到的油量。

示例1

输入

1

6

……

.##…

……

.#..#.

.#..##

……

输出

Case 1: 3

分析: 求有多少个 两个相邻的’#’

dfs

不过这题目的数据好像比较弱,, 发现自己写错了还能够A。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <set>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <string>
#include <vector>
#include <sstream>
#include <functional>
#include <algorithm>
using namespace std;

#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i<n;i++) ///[a,n)
#define dec(i,n,a) for(int i=n;i>=a;i--)///[n,a]
#define pb push_back
#define fi first
#define se second
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double PI=acos(-1.0);
const double E=2.718281828459045;
const double eps=1e-8;
const int INF=0x3f3f3f3f;
const int MOD=258280327;
const int N=50+5;
const ll maxn=1e6+5;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
int n,ans;
char a

;
bool vis

;
bool in(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<n) return true;
return false;
}
bool dfs(int x,int y)
{
rep(i,0,4)
{
int nx=x+dir[i][0],ny=y+dir[i][1];
if(in(nx,ny) && a[nx][ny]=='#')
{
a[x][y]='.';
if(!dfs(nx,ny))
{
a[nx][ny]='#';
ans++;
return true;
}
a[x][y]='#';
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
rep(cas,0,T)
{
scanf("%d",&n);
ans=0;
mem(vis,0);
rep(i,0,n) scanf("%s",a[i]);
rep(i,0,n)
{
rep(j,0,n)
{
if(a[i][j]=='#')
dfs(i,j);
}
}
printf("Case %d: %d\n",cas+1,ans);
}
return 0;
}


链接:https://www.nowcoder.net/acm/contest/76/B

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 65536K,其他语言131072K

64bit IO Format: %lld

题目描述

随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)

输入描述:

测试输入包含多条测试数据

每个测试数据的第1行分别给出可用的经费c(<1000000),道路数目n(n<10000),以及城市数目m(<100)。

接下来的n行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市v1、v2
(0<v1,v2<=m)
以及建设公路所需的成本h(h<100)。

输出描述:

对每个测试用例,输出Yes或No。

示例1

输入

20 10 5

1 2 6

1 3 3

1 4 4

1 5 5

2 3 7

2 4 7

2 5 8

3 4 6

3 5 9

4 5 2

输出

Yes

示例2

输入

10 2 2

1 2 5

1 2 15

输出

Yes

备注:

两个城市之间可能存在多条线路

分析: 最小生成树。。 kruskal算法(并查集+排序)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <
13c19
set>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <string>
#include <vector>
#include <sstream>
#include <functional>
#include <algorithm>
using namespace std;

#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i<n;i++) ///[a,n)
#define dec(i,n,a) for(int i=n;i>=a;i--)///[n,a]
#define pb push_back
#define fi first
#define se second
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double PI=acos(-1.0);
const double E=2.718281828459045;
const double eps=1e-8;
const int INF=0x3f3f3f3f;
const int MOD=258280327;
const int N=1e2+5;
const ll maxn=1e6+5;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
int par
;
struct Node
{
int u,v,w;
bool operator < (const Node& m)const
{
return w<m.w;
}
} a[maxn];
int Find(int x)///找根结点
{
int r=x;
while(par[r]!=r)
r=par[r];
int t=x;
while(t!=r)
{
int fa=par[t];
par[t]=r;
t=fa;
}
return r;
}
bool unite(int x,int y)//合并
{
x=Find(x),y=Find(y);
if(x!=y)
{
par[x]=y;
return true;
}
return false;
}
int main()
{
int n,k=0,m,c;
while(~scanf("%d%d%d",&c,&n,&m))
{
int num=0;
for(int i=1; i<=m; i++)
par[i]=i;
for(int i=1; i<=n; i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a,a+n);
int ans=0;
for(int i=1; i<=n; i++)
{
int u=a[i].u,v=a[i].v;
if(unite(u,v)) ans+=a[i].w;
}
printf("%s\n",ans>c?"No":"Yes");
}
return 0;
}


链接:https://www.nowcoder.net/acm/contest/76/C

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K

64bit IO Format: %lld

题目描述

给你两个升序排列的集合,求出两个集合的交集。

输入描述:

有多个测试用例,输入到文件结束。

对于每一个测试用例:

第一行输入两个整数n,
m(0<n,m<=1000000),
分别代表第一个集合和第二个集合的元素的数量。

第二行输入n个整数,表示第一个集合中的元素,元素之间用空格隔开。

第三行输入m个整数,表示第二个集合中的元素,元素之间用空格隔开。

两个集合中的元素范围在[-1000000000,1000000000]区间内。

输出描述:

每个测试用例用一行来输出两个集合的交集的所有元素(元素用空格隔开且按升序排列),若交集为空则输出”empty”。

示例1

输入

2 3

1 3

1 2 3

输出

1 3

备注:

交集为空的情况下,输出”empty”



分析: 直接用set_intersection 内存超限。。 (喔不是用了vector,最多不就10^6个元素?

暴力过了

MLE代码:

set<int>st1,st2;
vector<int>ANS;
int main(void)
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int x;
while(n--) scanf("%d",&x),st1.insert(x);
while(m--) scanf("%d",&x),st2.insert(x);
set_intersection(st1.begin(),st1.end(),st2.begin(),st2.end(),inserter(ANS,ANS.begin()));
int sz=ANS.size();
if(!sz) puts("empty");
else
{
for(int i=0; i<sz-1; i++) printf("%d ",ANS[i]);
printf("%d\n",ANS[sz-1]);
}
st1.clear();
st2.clear();
// printf("%d %d\n",st1.size(),st2.size());
}
return 0;
}


AC代码: 【暴力】

const int N=1e6+5;
const ll maxn=5e4;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
int A
,B
,result
;
int main(void)
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
rep(i,0,n) scanf("%d",&A[i]);
rep(i,0,m) scanf("%d",&B[i]);
int i = 0, j = 0;
int cnt = 0;
while(i < n && j < m)
{
if(A[i] == B[j])
{
result[cnt] = A[i];
i++;
j++;
cnt++;
}
else if(A[i] < B[j])
{
i++;
}
else
{
j++;
}
}
if(!cnt) puts("empty");
else
{
for(int i=0; i<cnt-1; i++) printf("%d ",result[i]);
printf("%d\n",result[cnt-1]);
}
}
return 0;
}


链接:https://www.nowcoder.net/acm/contest/76/F

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K

64bit IO Format: %lld

题目描述

从实验室出来后,你忽然发现你居然把自己的电脑落在了实验室里,但是实验室的老师已经把大门锁上了。更糟的是,你没有那个老师的电话号码。你开始给你知道的所有人打电话,询问他们有没有老师的电话,如果没有,他们也会问自己的同学来询问电话号码。那么,你能联系到老师并且拿到电脑吗。

输入描述:

存在多组测试样例

每组样例的第一行分别是两个整数n(1

const int N=50+5;
const ll maxn=5e4;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
bool d

;
int n,m;
void floyd()
{
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
d[i][j]=d[i][j]||(d[i][k]&&d[k][j]);
}
int main()
{
//fre;
while(~scanf("%d%d",&n,&m))
{
mem(d,0);
rep(i,0,m)
{
int x,y;
scanf("%d%d",&x,&y);
d[x][y]=1;
//d[y][x]=1;
}
floyd();
//for(int i=1;i<=n;i++) printf("d[1][%d]=%d\n",i,d[1][i]);
if(d[1]
) puts("Yes");
else puts("No");
}
return 0;
}


链接:https://www.nowcoder.net/acm/contest/76/H

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K

64bit IO Format: %lld

题目描述

老李见和尚赢了自己的酒,但是自己还舍不得,所以就耍起了赖皮,对和尚说,光武不行,再来点文的,你给我说出来1-8的全排序,我就让你喝,这次绝不耍你,你能帮帮和尚么?

输入描述:



输出描述:

1~8的全排列,按照全排列的顺序输出,每行结尾无空格。

示例1

输入

No_Input

输出

Full arrangement of 1~8

备注:

1~3的全排列 :

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

分析:STL中的next_permutation()函数

int main()
{
int a[8];
rep(i,0,8) a[i]=i+1;
do
{
rep(i,0,8) printf("%d%c",a[i],i==7?'\n':' ');
}
while(next_permutation(a,a+8));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图论
相关文章推荐