ICPC North Central NA Contest 2018

待补

  1. A后缀数组
  2. H概率

1. 题目分析

  • A:后缀数组待补
  • B: dp版题
  • C: 数论--小学数学奥赛
  • D: 大模拟
  • E: 签到
  • F: 思维签到
  • G: 有条件的最短路问题--卡内存,交换数组第二维和第三维
  • H: 概率待补
  • I: 羊狼菜思维题
  • J: 数学题--故意给出很大范围,实际用不到那么大范围

2. 题解

A.Pokegene

后缀数组

B.Maximum Subarrays

C.Rational Ratio

题意:给定一个循环小数的前半部分和循环节长度,该前半部分由不循环的部分和循环部分组成,循环部分只出现一次。求该小数对应的分数

题解:小学数学奥数题,把一个小数转换为分数的方法如下:

  1. 先把小数的整数部分拆出来,记为x
  2. 把小数部分的不循环部分拆出来,记为y
  3. 把小数部分的循环部分拆出来,记为z

    那么小数对应的分数为: x + (y - z) / (9..9(z个9)0..0(y个0))

    例如:1.6 1 => x = 1, y = 0, z = 6,则1 + (6-0) / 9 = 5 / 3

    123.456 2 => x = 123, y = 4, z = 56, 则123 + (456 - 4) / 990 = 61111/495
#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
string s;
int len;
cin >> s >> len;
int idx = s.find(".");
string first = "0", second = "0";
first = s.substr(0, idx);
second = s.substr(idx + 1);
// cout << first << " " << second << endl;
int len_second = second.size();
LL mother = 0;
for (int i = 1; i <= len; ++i) mother = mother * 10 + 9;
for (int i = 1; i <= len_second - len; ++i) mother *= 10;
// cout << mother << endl;
LL son = atoll(second.c_str()) - atoll(second.substr(0, len_second - len).c_str());
// cout << son;
LL gcd = __gcd(mother, son);
// cout << first << endl;
mother /= gcd, son /= gcd;
cout << son + mother * atoll(first.c_str()) << "/" << mother;
return 0;
}

D.Travel the Skies

题意:有 k 个机场,总共运行 n 天,有 m 架飞机,每架飞机有四个属性:u 代表起点,v 代表终点,d 代表哪天

起飞,z 表示飞机的容量 (可以乘多少人),在第 b 天,有 c 名希望旅游的乘客到达 a 机场,你可以安排旅客的起飞日

期 (到达日期当天或者之后的任何一天) 和目的地,问你是否能够保证每架飞机都能够装满,每架飞机飞行花费一天时

间,一架飞机只飞行一次但乘客可以飞行多次

题解:按照题意直接模拟即可,idx[a][d] 存储在 a 机场第 d 天起飞的飞机编号,cnt[a][d] 则表示在 a 机场第 d 天

的人数,从前向后遍历每一天,对于每一天遍历所有机场,尽量将每一架飞机装满,由于乘客可以多次飞行,所以需要

将每架飞机目的地第二天的人数加上这架飞机上的乘客数,如果某一天某个机场还有乘客没有起飞,则直接留到第二

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector> using namespace std; const int N = 1510;
const int M = 15; struct node {
int u, v, d, c;
}; int k, n, m;
int cnt[M][M];
vector<int> idx[M][M];
node p[N]; int main()
{
scanf("%d%d%d", &k, &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d%d", &p[i].u, &p[i].v, &p[i].d, &p[i].c);
idx[p[i].u][p[i].d].push_back(i);
}
for (int i = 1; i <= k * n; i++) {
int a, d, t;
scanf("%d%d%d", &a, &d, &t);
cnt[a][d] = t;
}
for (int d = 1; d <= n; d++) {
for (int a = 1; a <= k; a++) {
int len = (int)idx[a][d].size();
for (int b = 0; b < len; b++) {
int id = idx[a][d][b];
int t = min(cnt[a][d], p[id].c);
cnt[a][d] -= t;
p[id].c -= t;
cnt[p[id].v][d + 1] += t;
}
cnt[a][d + 1] += cnt[a][d];
}
}
int flag = 1;
for (int i = 1; i <= m; i++)
if (0 != p[i].c) flag = 0;
if (1 == flag) printf("optimal\n");
else printf("suboptimal\n");
return 0;
}

E. Euler's Number

题意:输入 n,计算 e

思路:签到题

#include <iostream>
#include <algorithm>
#include <cstdio> using namespace std; int n; double euler(int n)
{
double res = 0, fac = 1.0;
for (int i = 0; i <= n; i++) {
if (0 == i) res += fac;
else {
fac /= i;
res += fac;
}
}
return res;
} int main()
{
scanf("%d", &n);
printf("%.15lf\n", euler(n));
return 0;
}

F. Lipschitz Constant

题意:给定二维平面上 n 个点,求任意两点间斜率绝对值的最大值

题解:斜率绝对值的最大的两个点一定是 x 坐标相邻的两个点,按照 x 坐标排序,选择相邻的点计算斜率

证明:用反证法证明,如图,假设 AB 斜率绝对值最大,并且 AB 不相邻,如果 AB 之间存在一点 C 在 AB 直线 的下方,显然 kBC > kAB,如果 AB 之间存在另一点 D 在 AB 上方,同理会有 kDA > kAB,所以假设不成立,即斜率绝对值的最大的两个点一定是 x 坐标相邻的两个点

#include <iostream>
#include <algorithm>
#include <cstdio> using namespace std; const int N = 200010; struct node {
double x, y;
}; node p[N];
int n; bool cmp(node a, node b)
{
return a.x < b.x;
} int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
sort(p + 1, p + n + 1, cmp);
double res = 0;
for (int i = 2; i <= n; i++) {
double t = abs(p[i].y - p[i - 1].y) / abs(p[i].x - p[i - 1].x);
res = max(res, t);
}
printf("%.9lf\n", res);
return 0;
}

G. Tima goes to Xentopia

题意:有一张无向图N个点M条边,每条边有颜色,可能为白,红,蓝,同时每条边还有一个边权。小A从1号点出发走到n号点,问是否存在一条经过k1条红边,k2条蓝边的最短路,如果有,输出其最短路权值;如果没有,输出-1

N ~ 450, M ~ 1100, K1 * K2 <= 800

题解:

本题求解一个带有条件的最短路,是一个模板题。但是如果开始dis[450][800][800],那么mle,因此由k1*k2<=800,则dis[450][800][100],首先要判断k1和k2的大小,小的当成k2.有条件的最短路和没条件的最短路区别在于放入st数组和dis数组设置。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<LL, int> PLI;
LL const INF = 0x3f3f3f3f3f3f3f3f; struct point {
int id, r, b;
LL dis;
point(int _id, int _r, int _b, LL _dis) : id(_id), r(_r), b(_b), dis(_dis) {}
bool operator < (const point & t) const {
return dis > t.dis;
}
};
// int const N = 460, M = 1110;
LL dis[500][810][100];
int st[500][810][100];
int k1, k2, n, m, s, t, idx, e[3000], ne[3000], h[500], w[3000], color[3000]; void add(int a, int b, int c, int col) {
e[idx] = b, w[idx] = c, color[idx] = col, ne[idx] = h[a], h[a] = idx++;
} void Dijkstra() {
memset(dis, 0x3f, sizeof dis);
priority_queue<point> q;
dis[s][0][0] = 0;
q.push({s, 0, 0, 0});
while(!q.empty()) {
point temp = q.top();
q.pop();
if(st[temp.id][temp.r][temp.b]) continue; // 记录的时候要记点,边1,边2
st[temp.id][temp.r][temp.b] = 1;
for(int i = h[temp.id]; ~i; i = ne[i]) {
point t = {e[i], temp.r + (color[i] == 1), temp.b + (color[i] == 2), temp.dis + w[i]};
if(t.r > k1 || t.b > k2) continue;
if(t.dis < dis[t.id][t.r][t.b]) {
dis[t.id][t.r][t.b] = t.dis;
q.push(t);
}
}
}
printf("%lld\n", dis[t][k1][k2] == INF ? -1 : dis[t][k1][k2]);
} int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout); memset(h, -1, sizeof h);
cin >> n >> m >> k1 >> k2;
bool change = false;
if (k1 < k2) {
swap(k1, k2);
change = true;
}
for (int i = 1, a, b, weight, colorr; i <= m; ++i) {
cin >> a >> b >> weight >> colorr;
if (change) colorr = 3 - colorr;
add(a, b, weight, colorr);
add(b, a, weight, colorr);
}
cin >> s >> t;
// cout << s << " " << t << endl; Dijkstra();
return 0;
}

H. New Salaries

概率待补

I. Other Side

题意: 农夫有W匹狼,S只羊,C颗菜,当农夫不在场的时候狼会吃羊,羊会吃菜,但狼不吃菜。船的最大容量是K,农夫要将货物运到河对岸,问货物是否收到损失

题解:

羊必须和狼和菜分开,将狼和菜看成一个整体,狼和菜一起运,或者是只运羊。

(1)如果S < K || W + C < K,Yes

船上可以装下全部的羊,或者可以装下全部的狼和菜,可以把少的一方一直放在船上,把多的一方分多趟运到对岸。

(2)如果S == K && W + C <= 2 * K

船上放上全部的羊就满了,先把 K 只羊运到对岸,再把 K 个狼和菜运到对岸,再将羊运回起点,将剩下的狼和菜全部运到对岸,最后再运羊。可以发现,当W + C <= 2 * K时可以成功。

(3)如果 W + C == K && S <= 2 * K

#include <bits/stdc++.h>

using namespace std;

int main() {
int w, c, s, k;
cin >> w >> s >> c >> k;
int flg = 0;
if (s < k || w + c < k) flg = 1;
if (s == k && w + c <= 2 * k) flg = 1;
if (s <= 2 * k && w + c == k) flg = 1;
if (flg) cout << "YES";
else cout << "NO";
return 0;
}

J.Kaleidoscopic Palindromes

题意:求区间[a, b]内的所有数字中,2~k进制都是回文串的数字个数

a~2e6, k~1e5

题解:由于能够满足2~k进制都是回文串的数字个数非常少,因此只需要直接暴力枚举即可

#include <bits/stdc++.h>

using namespace std;

int a, b, k;

bool check(int x, int base) {
int pal[100], cnt = 0;
while (x) {
pal[cnt ++] = x % base;
x /= base;
} for (int i = 0; i < cnt; ++i) {
if (i < cnt - i - 1 && pal[i] != pal[cnt - i - 1]) return false;
}
return true;
} int main () {
cin >> a >> b >> k;
int sum = 0;
for (int i = a; i <= b; ++i) {
int j;
for (j = 2; j <= k; ++j) {
if (!check(i, j)) break;
} if (j == k + 1) sum ++;
}
cout << sum;
return 0;
}

ICPC North Central NA Contest 2018的更多相关文章

  1. Bumped! 2017 ICPC North American Qualifier Contest (分层建图+dijstra)

    题目描述 Peter returned from the recently held ACM ICPC World finals only to find that his return flight ...

  2. ACM ICPC, JUST Collegiate Programming Contest (2018) Solution

    A:Zero Array 题意:两种操作, 1 p v  将第p个位置的值改成v  2  查询最少的操作数使得所有数都变为0  操作为可以从原序列中选一个非0的数使得所有非0的数减去它,并且所有数不能 ...

  3. ACM ICPC, Amman Collegiate Programming Contest (2018) Solution

    Solution A:Careful Thief 题意:给出n个区间,每个区间的每个位置的权值都是v,然后找长度为k的区间,使得这个区间的所有位置的权值加起来最大,输出最大权值, 所有区间不重叠 思路 ...

  4. 2018-2019, ICPC, Asia Yokohama Regional Contest 2018 K

    传送门:https://codeforces.com/gym/102082/attachments 题解: 代码: /** * ┏┓ ┏┓ * ┏┛┗━━━━━━━┛┗━━━┓ * ┃ ┃ * ┃ ━ ...

  5. The North American Invitational Programming Contest 2018 D. Missing Gnomes

    A family of nn gnomes likes to line up for a group picture. Each gnome can be uniquely identified by ...

  6. The North American Invitational Programming Contest 2018 H. Recovery

    Consider an n \times mn×m matrix of ones and zeros. For example, this 4 \times 44×4: \displaystyle \ ...

  7. The North American Invitational Programming Contest 2018 E. Prefix Free Code

    Consider nn initial strings of lower case letters, where no initial string is a prefix of any other ...

  8. 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解

    题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...

  9. 2018-2019 ICPC, NEERC, Southern Subregional Contest

    目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...

随机推荐

  1. robot framework使用小结(三)

    robot framework采用行为驱动 新建测试案例baidu04,添加Library:Selenium2Library 右键项目名robotProject-->New Resource-- ...

  2. python脚本中调用其他脚本

    如果只关注脚本中调用他脚本直接看代码30行 PS:该脚本功能有:自动清理目录,创建目录,自动运行脚本,以此提升工作效率 import numpy as np import os from shutil ...

  3. [CF1216E] Numerical Sequence hard version

    题目 The only difference between the easy and the hard versions is the maximum value of k. You are giv ...

  4. html里输入框和密码框的提示文字怎么弄

    HTML5 新增属性,浏览器版本低于IE8应该不支持 placeholder 属性 placeholder 属性规定用以描述输入字段预期值的提示(样本值或有关格式的简短描述). 该提示会在用户输入值之 ...

  5. SQL Server 索引的含义和特点

    索引用于快速找出在某个列中某一特定值的行.不使索引,数据库必须从第一条记录开始读完整个表,直到找到相关行.如果表中查询的列有一个索引,数据库能快速到达一个位置去搜寻数据,而不必查看所有数据. 索引的含 ...

  6. sql 更新时 实现 数字字段自加1

    第一种:直接使用SQL语句,这种方式可以避免并发操作造成的数据不一致问题UPDATE 表名称 SET 列名称 = 列名称 + 1 WHERE …… 第二种:将上面的语句逻辑封装成一个存储过程,加上事务 ...

  7. python递归函数实现阶乘函数

    实现的效果如下: 参考www.cnblogs.com/yuanchenqi/articles/5828233.html f(5)=5*4*3*2*1=120   f(7)=7*6*5*4*3*2*1= ...

  8. 路由网关(Zuul)

    上一篇已经讲了微服务组件中的 分布式配置中心,本章讲述 由JAVA编写的服务路由网关Zuul… - Zuul 路由是微服务体系结构的一个组成部分.例如 / 可以映射到您的Web应用程序,/api/us ...

  9. centos7时间调整

    查看时区是否正确,命令date -R: 不正确先调整时区,命令tzselect: 安装ntp,命令yum install ntp: 同步时间,命令ntpdate cn.pool.ntp.org: 设置 ...

  10. HotSpot的类模型(2)

    在前一篇文章 HotSpot的二分模型中已经讲过,HotSpot采用了OOP-Klass模型描述Java的类和对象.Klass模型采用Klass类及相关子类来表示具体的Java类,可以理解这些类为Ja ...