2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019
1.A题
题意:给定第一行的值表示m列的最大值,第m行的值表示n行的最大值,问是否会行列冲突
思路:挺简单的,不过我在一开始理解题意上用了些时间,按我的理解是输入两组数组,找出每组最大数,若相等则输出possible,否则输出impossible,代码很直接用的C语言
1 #include<stdio.h>
2 int main(){
3 int r,c,i,j;
4 int s[110],b[110];
5 while(scanf("%d %d",&r,&c)!=EOF){
6 for(i=0;i<r;i++){
7 scanf("%d",&s[i]);
8 }
9 for(j=0;j<c;j++){
10 scanf("%d",&b[j]);
11 }
12 int max=s[0];
13 int min=b[0];
14 for(i=0;i<r;i++){
15 if(max<=s[i]){
16 max=s[i];
17 }
18 }
19 for(j=0;j<c;j++){
20 if(min<=b[j]){
21 min=b[j];
22 }
23 }
24 if(min==max){
25 printf("possible\n");
26 }
27 else printf("impossible\n");
28 }
29
30
31 }
2.G题
题意:复杂字符串中的e
思路:就是记录下e的个数,再双倍输出e其他不变,但要注意数组不要越界,第一次提交就出现了段错误,第二次才正确,看代码
#include<stdio.h>
#include<string.h>
char s[1000];
int main(){
//char s[1000];
while(scanf("%s",&s)!=EOF){
int i,m,k=0;
m=strlen(s);
// printf("%c\n",s[0]);
else if(s[0]=='h'){
for(i=1;i<m;i++){
if(s[i]=='e'){
k++;
}
}
printf("h");
for(i=0;i<k*2;i++){
printf("e");
}
printf("y\n");
} }
}
3.I题
题意:给定数组a,求公式的最大值
思路:求a数组平方的前缀和以及求a数组后缀和,遍历一遍即可
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>
typedef long long LL;
using namespace std;
int n, a[1000005];
LL l[1000005], r[1000005];
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) l[i] = l[i - 1] + a[i] * a[i];
for (int i = n; i >= 1; i--) r[i] = r[i + 1] + a[i];
LL ans = 0;
for (int i = 1; i < n; i++) ans = max(ans, l[i] * r[i + 1]);
printf("%lld\n", ans);
return 0;
}
4.F题
题意:给定n,求n=m^2-k^2
思路:分三种情况
1.对于n是奇数时,有(x+1)^2-x^2=2x+1
2.对于n是偶数时,有(x+2)^2-x^2=4(x+1)
3.除了上面两种情况,其他都impossible
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; LL n; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%lld", &n);
if(n & 1) printf("%lld %lld\n", n / 2 + 1, n / 2);
else if(n % 2 == 0 && n % 4) printf("impossible\n");
else printf("%lld %lld\n", (n - 4) / 4 + 2, (n - 4) / 4); return 0;
}
5.B题
题解:给定一字符串,最外层数字之间全用+,一层括号用*,两层用+,三层用*,以此类推
思路:每一层括号里的数字之间使用的符号相同,用栈存每一层的数字计算即可,需要手写栈,否则空间不够
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; const long long mod = 1e9 + 7; int n;
char s[15]; struct node
{
int val;
node* next;
node(int w, node *n){
val = w;
next = n;
}
}; class Stack{
public :
int sz;
node* head; Stack(){
head = NULL;
sz = 0;
}
bool empty(){
return !sz;
}
int top(){
if(!empty()) return head->val;
return 0;
}
node *push(int val){
head = new node(val, head);
sz++;
return head;
}
void pop(){
if(empty()) return ;
node *tp = head;
head = head->next;
sz--;
delete tp;
}
int size(){
return sz;
}
}sk[300005]; int change(char s[]){
int res = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) res = res * 10 + s[i] - '0';
return res;
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d", &n);
int cnt = 0;
for (int i = 1; i <= n; i++){
scanf("%s", s);
if(s[0] == '(') cnt++;
else if(s[0] == ')'){
if(cnt & 1){
LL ans = 1;
while(sk[cnt].size()) ans = ans * sk[cnt].top() % mod, sk[cnt].pop();
cnt--;
sk[cnt].push(ans);
}else{
LL ans = 0;
while(sk[cnt].size()) ans = (ans + sk[cnt].top()) % mod, sk[cnt].pop();
cnt--;
sk[cnt].push(ans);
}
}else{
sk[cnt].push(change(s));
}
}
LL ans = 0;
while(sk[0].size()) ans = (ans + sk[0].top()) % mod, sk[0].pop();
printf("%lld\n", ans); return 0;
}
6.C题
题解:可建 k 座桥,建桥后山的高度忽略不计,求从底部(第 r 行)走到顶部(第 1 行)的
路线中最小值最大是多少。
思路:二分答案,用 bfs 跑图即可,因为每一个单元格会重复走,对于走的距离循环来优化 bfs。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n, m, k;
int mp[1005][1005];
bool vis[1005][1005];
int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; struct node
{
int x, y;
node() {}
node(int x, int y) : x(x), y(y) {}
}; int bfs(int val){
memset(vis, 0, sizeof(vis));
queue<node> q[k + 2];
for (int i = 1; i <= m; i++) vis[n][i] = true, q[mp[n][i] < val ? 1 : 0].push(node(n, i));
for (int i = 0; i <= k; i++){
while(q[i].size()){
node front = q[i].front();
if(front.x == 1) return 1;
q[i].pop();
for (int j = 0; j < 4; j++){
int x = front.x + d[j][0], y = front.y + d[j][1];
if(x < 1 || x >= n || y < 1 || y > m) continue;
if(!vis[x][y]){
vis[x][y] = true;
q[mp[x][y] < val ? i + 1 : i].push(node(x, y));
}
}
}
} return 0;
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); int l = 0, r = 0;
scanf("%d %d %d", &n, &m, &k);
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
scanf("%d", &mp[i][j]);
r = max(r, mp[i][j]);
}
}
int ans = l;
while(l <= r){
int mid = (l + r) >> 1;
if(bfs(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
}
printf("%d\n", ans); return 0;
}
7.D题
题解:有一个 n 面的骰子,现在最多可以玩 k 轮,如果在 i(i<=k)轮达到了期望水平(即
期望的骰子分数),那么就会终止,否则继续,问最终游戏的期望分数。
思路:求出第 i 轮的期望分数为 socre1,对于第 i + 1 轮来说,进行第 i + 1 轮
的条件是第 i 轮没有到达期望分数 score1,那么第 i + 1 轮的期望分数为
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n, k;
int p[10005]; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d %d", &n, &k);
double ans = 0;
for (int i = n; i >= 1; i--) p[i] = p[i + 1] + i;
for (int i = 1; i <= k; i++){
if(i == 1){
ans = 1.0 * p[i] / n;
}else{
ans = 1.0 * (p[(int)floor(ans) + 1] + floor(ans) * ans) / n;
}
}
printf("%.7lf\n", ans); return 0;
}
8.E题
题解:移除最多一半的边使得图没有环。
思路:将所有边分成两部分,第一部分为 u < v,第二部分为 v > u,将小的边
集合删去
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n, m; vector<int> v1, v2; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d %d", &n, &m);
for (int i = 1, u, v; i <= m; i++){
scanf("%d %d", &u, &v);
if(u < v) v1.push_back(i);
else v2.push_back(i);
}
if(v1.size() > v2.size()){
printf("%d\n", v2.size());
for (auto x : v2) printf("%d\n", x);
}else{
printf("%d\n", v1.size());
for (auto x : v1) printf("%d\n", x);
} return 0;
}
9.H题
题解:
给定起始位置的行(数字 1~11)和列(字母 a~k)和末位置的行和列,求两步(一步的
长度不一定是 1)走到末位置的中间点的数量。
思路:
枚举所有棋的格子,同时满足从起始位置一步到所枚举的格子和所枚举
的格子一步到末位置即答案 + 1
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; char c1, c2;
int x, y; bool solve(char sl, int sr, char el, int er){
if(sl == el) return sr != er;
if(sl > 'f') sr += sl - 'f';
if(el > 'f') er += el - 'f';
if(sr == er) return true;
if(el - sl == er - sr) return true;
return false;
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%c%d %c%d", &c1, &x, &c2, &y);
int ans = 0;
for (int i = 'a'; i <= 'k'; i++){
int num = 11 - abs('f' - i);
for (int j = 1; j <= 11; j++){
if(j > num) break;
if(solve(c1, x, i, j) && solve(i, j, c2, y)) ans++;
}
}
printf("%d\n", ans); return 0;
}
10.J题
题解:给你 i 到 j 路线长度的平均值(1 <= i, j <= n),求出原始 DAG 路径图
思路:
拓扑排序给你的平均路径图,建立新的拓扑图,设置相邻顶点间的边数
为 1,边值为平均路径。枚举起始点和终点,统计间接到达终点的路数和路径总
长,算出是否要添加一条新的从起始点到终点的直接路径,同时如果有间接路径
时要保证新添的路径长度小于平均值。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n, in[105], toposort_v[105], toposort_p[105], num[105][105];
LL dag_ans[105][105];
LL dag_ave[105][105], dag_new[105][105]; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d", &n);
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
scanf("%lld", &dag_ave[i][j]);
if(dag_ave[i][j] > 0) in[j]++;
}
} // toposort to new dag
queue<int> q;
int cnt = 0;
for (int i = 1; i <= n; i++) if(!in[i]) q.push(i), toposort_v[++cnt] = i;
while(q.size()){
int u = q.front();
q.pop();
for (int v = 1; v <= n; v++){
if(dag_ave[u][v] > 0){
in[v]--;
if(in[v] == 0) q.push(v), toposort_v[++cnt] = v;
}
}
}
for (int i = 1; i <= n; i++) toposort_p[toposort_v[i]] = i; // new dag
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
dag_new[i][j] = dag_ave[toposort_v[i]][toposort_v[j]];
}
} // orginal ans_dag
memset(dag_ans, -1, sizeof(dag_ans));
for (int i = 1; i < n; i++){
if(dag_new[i][i + 1] > 0) dag_ans[i][i + 1] = dag_new[i][i + 1], num[i][i + 1] = 1;
}
for (int len = 2; len <= n; len++){
for (int i = 1; i + len <= n; i++){
int j = i + len;
// i -> k -> j ways' number and weight
LL sum = 0;
for (int k = i + 1; k < j; k++){
if(dag_ans[i][k] > 0 && num[k][j] > 0){
num[i][j] += num[k][j];
sum += dag_ans[i][k] * num[k][j] + dag_new[k][j] * num[k][j];
}
}
// if add a path, ave = (sum + x) / (num[i][j] + 1), x is new path's weight
LL x = dag_new[i][j] * (num[i][j] + 1) - sum;
if((num[i][j] == 0 && dag_new[i][j] > 0) || (num[i][j] && x > 0 && dag_new[i][j] > x)){ // 保证直连的线长度小于间接连得线,所以直连的线小于平均值
dag_ans[i][j] = x;
num[i][j]++;
}
}
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
int x = toposort_p[i], y = toposort_p[j];
printf("%lld%c", dag_ans[x][y], j == n ? '\n' : ' ');
}
} return 0;
}
11.K题
题解:
给定 n 件物品和他们的重量以及所有组合重量,求是否存在这 n 件物品的重量
来满足这些组合
思路:
将所有重量存入 multiset 中,每次考虑最大的次大的,必能得到 n 个物
品中一个物品的重量,从 multiset 中删除与此重量有关的所有组合,若找不到,
输出 impossible。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n, ans[25]; multiset<int> s; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d", &n);
for (int i = 0, x; i < (1 << n); i++) scanf("%d", &x), s.insert(x);
int cnt = 0;
for (int i = 1; i <= n; i++){
if(s.size() < 2) break;
cnt++;
int x = *prev(s.end()) - *prev(prev(s.end()));
ans[i] = x;
for (auto it = s.begin(); it != s.end(); it++){
int y = *it;
auto p = s.upper_bound(x + y);
p = prev(p);
if(p == s.end() || p == it || *p != x + y){
printf("impossible\n");
return 0;
}
s.erase(p);
}
}
if(s.size() != 1 || *s.begin() != 0 || cnt < n) printf("impossible\n");
else for (int i = 1; i <= n; i++) printf("%d\n", ans[i]); return 0;
}
12.L题
题解:
两个救生员中最靠近游泳者是监控者。找到两个救生员的坐标,使得救生员监控
的游泳者数量相同,最多有一个游泳的离两个救生员距离相同。
思路:
同 https://ac.nowcoder.com/acm/contest/883/H,将所有游泳的根据坐
标排序,用一直线划分成两部分,线的两个无穷远处为端点,若游泳的数量为奇
数,那么此线需经过中间点。设中间点为(x,y)Max 设为无穷大例: n 为偶数 (x -
Max, y - 1), (x + Max, y) n 为奇数 (x - Max, y - 1), (x + Max, y + 1)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue> typedef long long LL;
using namespace std; int n;
struct node
{
LL x, y;
bool operator <(const node &rhs)const{
return x == rhs.x ? y < rhs.y : x < rhs.x;
}
}a[100005]; int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%lld %lld", &a[i].x, &a[i].y);
sort(a + 1, a + 1 + n);
int mid = (n + 2) / 2;
LL MAX = 10000000000LL;
LL x = a[mid].x, y = a[mid].y;
if(n & 1){
printf("%lld %lld\n", x - MAX, y - 1);
printf("%lld %lld\n", x + MAX, y + 1);
}else{
printf("%lld %lld\n", x - MAX, y - 1);
printf("%lld %lld\n", x + MAX, y);
} return 0;
}
2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019的更多相关文章
- ICPC训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019
I题 求 a 数组平方的前缀和和求 a 数组后缀和,遍历一遍即可 AC代码 #include<iostream>#include<cmath>using namespace s ...
- 03.14 ICPC训练联盟周赛,Preliminaries for Benelux Algorithm Programming Contest 2019
A .Architecture 题意:其实就是想让你找到两行数的最大值,然后比较是否相同,如果相同输出'possible',不同则输出'impossible' 思路:直接遍历寻找最大值,然后比较即可 ...
- Preliminaries for Benelux Algorithm Programming Contest 2019
A. Architecture 如果行最大值中的最大值和列最大值中的最大值不同的话,那么一定会产生矛盾,可以手模一个样例看看. 当满足行列最大值相同条件的时候,就可以判定了. 因为其余的地方一定可以构 ...
- 2020.3.21--ICPC训练联盟周赛Benelux Algorithm Programming Contest 2019
A Appeal to the Audience 要想使得总和最大,就要使最大值被计算的次数最多.要想某个数被计算的多,就要使得它经过尽量多的节点.于是我们的目标就是找到 k 条从长到短的链,这些链互 ...
- ICPC训练周赛 Benelux Algorithm Programming Contest 2019
D. Wildest Dreams 这道题的意思是Ayna和Arup两人会同时在车上一段时间,在Ayna在的时候,必须单曲循环Ayna喜欢的歌,偶数段Ayna下车,若此时已经放了她喜欢的那首歌,就要将 ...
- 2020.3.28-ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016
A.Majestic 10 签到题. #include<iostream> #include<cstdio> #include<cstring> #include& ...
- 2014 Benelux Algorithm Programming Contest (BAPC 14)E
题目链接:https://vjudge.net/contest/187496#problem/E E Excellent Engineers You are working for an agency ...
- 计蒜客 ACM训练联盟周赛 第一场 从零开始的神棍之路 暴力dfs
题目描述 ggwdwsbs最近被Zeratul和Kyurem拉入了日本麻将的坑.现在,ggwdwsbs有13张牌,Kyurem又打了一张,加起来有14张牌.ggwdwsbs想拜托你帮他判断一下,这14 ...
- 计蒜客 28449.算个欧拉函数给大家助助兴-大数的因子个数 (HDU5649.DZY Loves Sorting) ( ACM训练联盟周赛 G)
ACM训练联盟周赛 这一场有几个数据结构的题,但是自己太菜,不会树套树,带插入的区间第K小-替罪羊套函数式线段树, 先立个flag,BZOJ3065: 带插入区间K小值 计蒜客 Zeratul与Xor ...
随机推荐
- css之px、em、rem
rem是css3新定义的设置字体大小属性,常用的两种字体大小设置有下面2种:1. px为单位2.em为单位(百分比用法跟em类似) PX为单位 在Web页面初期制作中,我们都是使用"px&q ...
- JVM加载class文件的一些理解
Java是一种动态解释型语言,类(class)只有被加载到JVM中后才能运行.每当一个Java程序运行时,都会有一个对应的JVM实例,只有当程序运行结束后,这个JVM才会退出.JVM实例通过调用类的m ...
- JS 处理图片平铺问题
background: url("../../../assets/image/center.png") no-repeat; // 让图片不平铺 overflow: hidde ...
- wireshark 解密加密报文
wireshark 解密IPSec加密后的报文 序言 wireshark作为一款非常优秀的抓包工具,支持了各种各样的网络协议,成为了网络开发中必不可少的工具之一.一般而言,对于普通的网络数据包,wir ...
- vue-cli-service build 环境设置
zhidao zhouzongshuo的那个是使用vue-cli3打包项目,通过配置不同的指令给项目设置不一样的配置. npm run serve时会把process.env.NODE_ENV设置为' ...
- 【第十二篇】- Git 服务器搭建之Spring Cloud直播商城 b2b2c电子商务技术总结
Git 服务器搭建 上一章节中我们远程仓库使用了 Github,Github 公开的项目是免费的,2019 年开始 Github 私有存储库也可以无限制使用. 这当然我们也可以自己搭建一台 Git 服 ...
- 分布式必备理论基础:CAP和BASE
大家好,我是老三,今天是没有刷题的一天,心情愉悦,给大家分享两个简单的知识点:分布式理论中的CAP和BASE. CAP理论 什么是CAP CAP原则又称CAP定理,指的是在一个分布式系统中,Consi ...
- FastAPI(7)- get 请求 - 详解 Path
前言 上一篇讲了可以为查询参数添加额外的校验和元数据,Query 库:https://www.cnblogs.com/poloyy/p/15306809.html 这篇讲可以为路径查询添加额外的校验和 ...
- 如何获取PHP命令行参数
使用 PHP 开发的同学多少都会接触过 CLI 命令行.经常会有一些定时任务或者一些脚本直接使用命令行处理会更加的方便,有些时候我们会需要像网页的 GET . POST 一样为这些命令行脚本提供参数. ...
- composer 忽略版本检测
今天安装插件的时候,直接不能安装,提示其他插件版本要求 tip:心细的朋友可能发现黄色部分提示了,提示我们升级composer,现在composer2.0已经发布了,赶快升级吧传送门 https:// ...