地址:点击打开链接

A 石油采集

思路:

二维矩阵四连通图是一个二分图,其实仔细想想就是将相邻的“#”建图,然后在找最大匹配。匈牙利算法即可。也可以dfs,代码如下:

匈牙利:

#include<iostream>
#include<stdlib.h>
#include<cstdio>
#include<cstring>
#include<string>
#include<time.h>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<map>
#include<set>
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,line[2555][2555],M[105][105],pre[10005],vis[10005];
char a[105][105];int Find(int x){for(int i=1;i<=n*n;i++){if(!vis[i]&&line[x][i]){vis[i]=1;if(pre[i]==-1||Find(pre[i])){pre[i]=x;return 1;}}}return 0;
}int main()
{int T,count=1;scanf("%d",&T);while(T--){memset(line,0,sizeof(line));memset(pre,-1,sizeof(pre));scanf("%d",&n);getchar();for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){scanf("%c",&a[i][j]);}getchar();}int k=1;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){M[i][j]=k++;}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(a[i][j]=='#'&&(i+j-1)%2){  //奇偶区分for(int l=0;l<4;l++){int xx=i+dir[l][0];int yy=j+dir[l][1];if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&a[xx][yy]=='#'){line[M[i][j]][M[xx][yy]]=1;}}}}}int ans=0;for(int i=1;i<=n*n;i++){memset(vis,0,sizeof(vis));if(Find(i))ans++;}printf("Case %d: %d\n",count,ans);count++;}return 0;
}

DFS代码:

#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>using namespace std;const int maxn = 55;
const int INF = 0x3f3f3f3f;
int N;
char MAP[maxn][maxn];
int a[4][2] = {1,0,0,1,-1,0,0,-1};
int number = 0;
bool check(int x,int y)
{return (x >=0 && y >= 0 && y < N && x < N);
}
bool dfs(int x,int y)
{for(int i = 0 ; i <= 3; i ++){int hx = x + a[i][0];int yx = y + a[i][1];if(check(hx,yx) && MAP[hx][yx] == '#'){MAP[x][y] = '.';if(dfs(hx,yx) == false){number++;MAP[hx][yx] = '.';MAP[x][y] = '.';return true;}MAP[x][y] = '#';//回溯}}return false;
}
int main()
{int T;scanf("%d",&T);int CASE = 1;while(T--){scanf("%d",&N);for(int i =  0; i < N ; i ++){scanf("%s",&MAP[i]);}for(int i = 0; i < N ; i ++){for(int j = 0; j < N ; j ++){if(MAP[i][j] == '#'){dfs(i,j);}}}printf("Case %d: %d\n",CASE++,number);}return 0;
}

B 道路建设

思路:水题。裸的最小生成树。kruskal模板即可:

#include<map>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 10000+100
#define PI acos(-1.0)
#define INF 1e9
using namespace std;
typedef long long ll;
int c,n,m;
int p[maxn],w[maxn],u[maxn],v[maxn],r[maxn];int cmp(const int i,const int j){return w[i]<w[j];
}int findset(int x){return p[x]==x?x:p[x]=findset(p[x]);
}int kruskal(){int ans=0;for(int i=0;i<n;i++)p[i]=i;for(int i=0;i<m;i++)r[i]=i;sort(r,r+m,cmp);for(int i=0;i<m;i++){int e=r[i];int x=findset(u[e]);int y=findset(v[e]);if(x!=y){ans+=w[e];p[x]=y;}}return ans;
}int main(){cin>>c>>m>>n;for(int i=0;i<m;i++){cin>>u[i]>>v[i]>>w[i];}int ans=kruskal();if(ans>c) cout<<"No"<<endl;else cout<<"Yes"<<endl;return 0;
}

C 求交集

思路:

水题啊!想太复杂了,因为数据是上升序的,所以只需要暴力判断即可,代码如下:

#include <cstdio>
#include <cstring>
const int MAXN=1e6+10;
int n,m;
int a[MAXN],b[MAXN];
bool flag;void print(int x)
{if (flag)printf("%d",x);elseprintf(" %d",x);flag=false;
}int main()
{flag=true;while (scanf("%d%d",&n,&m)==2){for (int i=1;i<=n;i++)scanf("%d",&a[i]);for (int i=1;i<=m;i++)scanf("%d",&b[i]);int i=1,j=1;while (i<=n && j<=m){if (a[i]==b[j])print(a[i]),i++,j++;elseif (a[i]<b[j])i++;elsej++;}if (flag)printf("empty");printf("\n");flag=true;}return 0;
}

D 小明的挖矿之旅

思路:由于只能向右或者向下走,所以变成了一张有向无环图。我们只要比较出度为0的点的个数和入度为0的点的个数即可。

注意几种特殊情况:全是孤立点、没有点

代码:(参考:点击打开链接)

#include <bits/stdc++.h>
using namespace std;const int INF = 0x7FFFFFFF;
const int maxn = 1100;
char s[maxn][maxn];
int in[maxn * maxn];
int ou[maxn * maxn];
int n, m;int out(int x, int y) {if(x < 0 || x >= n) return 1;if(y < 0 || y >= m) return 1;return 0;
}int main() {while(~scanf("%d%d", &n, &m)) {for(int i = 0; i < n; i ++) {scanf("%s", s[i]);}memset(in, 0, sizeof in);memset(ou, 0, sizeof ou);for(int i = 0; i < n; i ++) {for(int j = 0; j < m; j ++) {if(s[i][j] == '#') continue;if(out(i, j + 1) == 0 && s[i][j + 1] != '#') {in[i * m + j + 1] ++;ou[i * m + j] ++;}if(out(i + 1, j) == 0 && s[i + 1][j] != '#') {in[(i + 1) * m + j] ++;ou[i * m + j] ++;}}}int sum1 = 0, sum2 = 0, sum3 = 0;for(int i = 0; i < n; i ++) {for(int j = 0; j < m; j ++) {if(s[i][j] == '#') continue;if(in[i * m + j] == 0) sum1 ++;if(ou[i * m + j] == 0) sum2 ++;sum3 ++;}}if(sum3 == 0) {printf("%d\n", 0);return 0;}if(sum1 == sum3 && sum2 == sum3) {printf("%d\n", sum1 - 1);}elseprintf("%d\n", max(sum1, sum2));}return 0;
}

E 通知小弟

思路: 先对图进行强连通分量缩点,因为一个强连通分量内部一旦有一个人得到通知,所有人都可以得到通知。缩点后形成了一张有向无环图,我们只要通知到新图中那些入度为0的点,所有的人都能得到通知。对于无解的情况,我们只要检查HA能通知到的人是否cover了新图中所有入度为0的点。

代码:

#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<iomanip>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std ;
const int N=505 ;
const int M=505*505 ;
const int inf=1<<20 ;
struct node
{int  u,v,next ;
}edge[M] ;
int head[N] ,low[N],dnf[N],vis[N],stack[N],in[N],belong[N],cost[N],f[505];
int dep,cnt,top,sum ;void add(int u ,int v)
{edge[top].u=u ;edge[top].v=v;edge[top].next=head[u] ;head[u]=top++;
}void tarjan(int u)
{int x ;low[u]=dnf[u]=++dep ;stack[cnt++]=u;vis[u]=1;for(int i = head[u] ; i!=-1; i=edge[i].next){int v=edge[i].v ;if(!dnf[v]){tarjan(v) ;low[u] = min( low[u] , low[v])  ;}else if(vis[v])low[u] =  min( low[u] , dnf[v] )  ;}if(low[u]==dnf[u]){sum++ ;int z=inf ;do{x = stack[--cnt] ;vis[x] = 0 ;belong[x]=sum;z = min(z,f[x]) ;}while(x!=u) ;cost[sum] = z ;//更新一个联通分支花费最小的 ;}
}int main()
{int n,m ,u,v,x;while(~scanf("%d%d",&n,&m)){top = 0 ;memset(head,-1,sizeof(head));for(int i = 1 ; i <= m;i++)scanf("%d", &f[i]);for(int i = 1 ; i <= n ; i++){scanf("%d", &x);for (int j = 0; j < x; j++) {scanf("%d",&u) ;add(i,u) ;}}memset(low,0,sizeof(low)) ;memset(dnf,0,sizeof(dnf)) ;memset(vis,0,sizeof(vis)) ;memset(in,0,sizeof(in)) ;dep=sum=cnt=0 ;for(int i  = 1 ; i <= n ; i++){if(!dnf[i])tarjan(i) ;}for(int i = 1 ; i <= n ; i++)//缩点{for(int j = head[i] ; j!=-1 ;j=edge[j].next){v=edge[j].v ;if(belong[i]!= belong[v])//不同强连通分支{in[belong[v]]++ ;//记录入读}}}int ans = 0 , flag= 1;bool ok;for(int i = 1 ; i <= sum ; i++)if(!in[i]) {ok = false;for (int j = 1; j <= m; j++)if (belong[f[j]] == i) {ok = true;break;}if (!ok) {flag = 0;break;}ans++;}if (flag) printf("%d\n", ans);else puts("-1");}return 0 ;
}

F Call to your teacher

思路:

bfs暴力即可

代码:

#include<map>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 2000+100
#define PI acos(-1.0)
#define INF 1e9
using namespace std;
typedef long long ll;
int n,m;
int vis[maxn];
vector<int>G[maxn];bool bfs(){queue<int>Q;Q.push(1);vis[1]=true;while(!Q.empty()){int x=Q.front();Q.pop();vis[x]=true;// if(x==n) return true;for(int i=0;i<(int)G[x].size();i++){if(G[x][i]==n) return true;if(!vis[G[x][i]]) Q.push(G[x][i]);else continue;}}return false;
}int main(){cin>>n>>m;int x,y;memset(vis,0,sizeof(vis));for(int i=0;i<=n;i++) G[i].clear();for(int i=0;i<m;i++){cin>>x>>y;G[x].push_back(y);}if(bfs()){printf("Yes\n");}else {printf("No\n");}return 0;
}

G 老子的意大利炮呢

思路:可以枚举三种配件按什么顺序获得,得到之后再走到终点即可。最后阶段可以bfs。

代码:

#include <bits/stdc++.h>
using namespace std;const int INF = 0x7FFFFFFF;
const int maxn = 110;
char s[maxn][maxn];
int dis[maxn][maxn];
int ans;
int n, m;
int sx, sy;
int x[5], y[5];
int ex, ey;
int t[5];
int dir[4][2] = {{-1, 0},{1, 0},{0, -1},{0, 1},};
int out(int x, int y) {if(x < 0 || x >= n) return 1;if(y < 0 || y >= m) return 1;return 0;
}
void bfs() {queue<int> q;q.push(ex * m + ey);dis[ex][ey] = 0;while(!q.empty()) {int top = q.front();q.pop();int nowx = top / m;int nowy = top % m;for(int i = 0; i < 4; i ++) {int tx = nowx + dir[i][0];int ty = nowy + dir[i][1];if(out(tx, ty)) continue;if(s[tx][ty] == '#') continue;if(dis[nowx][nowy] + t[0] + t[1] + t[2] + 1 > dis[tx][ty]) continue;dis[tx][ty] = dis[nowx][nowy] + t[0] + t[1] + t[2] + 1;q.push(tx * m + ty);}}
}int D(int x1, int y1, int x2, int y2) {return abs(x1 - x2) + abs(y1 - y2);
}int main() {scanf("%d%d", &n, &m);for(int i = 0; i < n; i ++) {scanf("%s", s[i]);for(int j = 0; j < m; j ++) {dis[i][j] = INF;}}scanf("%d%d", &sx, &sy);sx --; sy --;for(int i = 0; i < 3; i ++) {scanf("%d%d", &x[i], &y[i]);x[i] --;y[i] --;}scanf("%d%d", &ex, &ey);ex --; ey --;for(int i = 0; i < 3; i ++) {scanf("%d", &t[i]);}bfs();ans = INF;for(int i = 0; i < 3; i ++) {if(dis[x[i]][y[i]] == INF) continue;int tmp = 0;int p0, p1, p2;if(i == 0) {p0 = 0;p1 = 1;p2 = 2;} else if(i == 1) {p0 = 1;p1 = 0;p2 = 2;} else {p0 = 2;p1 = 1;p2 = 0;}tmp = min(D(sx, sy, x[p1], y[p1]) * 1+ D(x[p1], y[p1], x[p2], y[p2]) * (t[p1] + 1)+ D(x[p2], y[p2], x[p0], y[p0]) * (t[p1] + t[p2] + 1),D(sx, sy, x[p2], y[p2]) * 1+ D(x[p1], y[p1], x[p2], y[p2]) * (t[p2] + 1)+ D(x[p1], y[p1], x[p0], y[p0]) * (t[p1] + t[p2] + 1));tmp += dis[x[i]][y[i]];ans = min(ans, tmp);}cout << ans << endl;return 0;
}

H 老子的全排列呢

思路:

dfs求全排列即可

代码:

#include<map>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 1000+100
#define maxm 200000+100
#define PI acos(-1.0)
#define INF 1e9
using namespace std;
typedef long long ll;
int m=8;
int vis[1000000];
int a[1000000];
void dfs(int n)
{if(n==m){for(int j=1;j<=m-1;j++)printf("%d ",a[j]);printf("%d",a[m]);printf("\n");}n++;for(int i=1;i<=m;i++){if(vis[i])  continue;vis[i]=1;a[n]=i;dfs(n);vis[i]=0;}
}
int main()
{memset(vis,0,sizeof(vis));dfs(0);
}

2018年全国多校算法寒假训练营练习比赛(第四场)相关推荐

  1. 【题集】牛客网·2018年全国多校算法寒假训练营练习比赛(第二场)

    原文链接:2018年全国多校算法寒假训练营练习比赛(第二场) A 吐泡泡 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Form ...

  2. 【题集·待解决】牛客网·2018年全国多校算法寒假训练营练习比赛(第二场)

    原文链接:2018年全国多校算法寒假训练营练习比赛(第二场) A 吐泡泡 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Form ...

  3. 牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) H.了断局-递推

    H.了断局 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 链接:https://www.nowcode ...

  4. 2018年全国多校算法寒假训练营练习比赛(第二场)B - TaoTao要吃鸡

    链接:https://www.nowcoder.com/acm/contest/74/B 来源:牛客网 题目描述 Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了, 和绝地 ...

  5. 2018年全国多校算法寒假训练营练习比赛(第一场)G 圆圈

    链接:https://www.nowcoder.com/acm/contest/67/G 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...

  6. 2018年全国多校算法寒假训练营练习比赛(第一场)F. 大吉大利,今晚吃鸡——跑毒篇(模拟)

    链接:https://www.nowcoder.com/acm/contest/67/F 来源:牛客网 题目描述 现在有一款很火的游戏playerunknown's battlegrounds,人称& ...

  7. 2018年全国多校算法寒假训练营练习比赛(第一场)G. 圆圈

    链接:https://www.nowcoder.com/acm/contest/67/G 来源:牛客网 题目描述 圈圈圆圆圈圈,lulu小朋友最近看喜羊羊看多了,老是受刺激就画圆圈,听到小于8的数字时 ...

  8. 2018年全国多校算法寒假训练营练习比赛(第一场)D. N阶汉诺塔变形(找规律)

    链接:https://www.nowcoder.com/acm/contest/67/D 来源:牛客网 题目描述 相信大家都知道汉诺塔问题.那么现在对汉诺塔问题做一些限制,成为一个新的玩法. 在一个底 ...

  9. 2018年全国多校算法寒假训练营练习比赛(第一场)C. 六子冲(模拟)

    链接:https://www.nowcoder.com/acm/contest/67/C 来源:牛客网 题目描述 六子冲是流传于中国民间的一类棋类游戏.由于这个游戏对环境的要求不高,孩子们大都是在光滑 ...

  10. 牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) A.吐泡泡-STL(stack)

    不好玩,一堆板子,太菜了,被打爆了,B一直wa60%,D一直wa80%,D改了多组输入就过了... A.吐泡泡 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...

最新文章

  1. 从复现人类智能到挑战AI大工程,智能计算正经历什么考验?
  2. 设置clion执行前的cmake命令,和CMAKELIST.txt不冲突
  3. Visual Studio—— IntelliSense: #error 指令: Please use the /MD switch for _AFXDLL builds
  4. 20145239杜文超 《Java程序设计》第7周学习总结
  5. sql2012 ssrs_SQL Server Reporting Services(SSRS)共享数据集
  6. pb9.0.3 8836补丁包_英语单数/复数名词傻傻分不清楚?3种不规则形态一次性搞懂!...
  7. 期末作业面向对象程序设计(Java)“猜拳游戏”
  8. 微信小程序经典开源代码汇总
  9. Oracle账号及客户端下载
  10. 局域网DNS服务器搭建
  11. 8-思科防火墙:Cisco ASA uRPF运用
  12. 外贸B2C系列:google企业邮箱设置
  13. 微信群发提示频繁怎么办?
  14. 下载Eclipse压缩包
  15. 有限差分法求解高阶导数
  16. 2017年中秋前记录
  17. 【开发日常】【Java】Java小程序汽车租赁
  18. 复赛名单公布!2022隐私计算HACKATHON大赛火热进行中!
  19. 如何把python可视化到前端_Python一行代码搞定炫酷可视化,就用这个工具!
  20. 高速缓冲存储器-cache

热门文章

  1. 【软件工程】02组软件工程组队项目——课程管理小助手需求文档
  2. 推荐一个免费空间(www.qsh.eu)
  3. 蓝桥杯scratch集训操作题:数的判断和计算
  4. npoi html富文本,c#NPOI导出
  5. SQL SERVER触发器回顾(联级删除)
  6. Android8.0 ZenMode 静音模式
  7. android 源码分析 内置 sd storage,Android开罐头———外部存储与内部存储完全解析...
  8. ubuntu20.04 百度输入法的配置
  9. 2021年中国铁矿石产业链供需整体分析,上游勘察储量下滑,进口依赖加重,下游需求增长「图」
  10. 植物浮雕艺术工作坊:让孩子探究自然之美