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. 阿里巴巴开源canal 工具数据同步异常CanalParseException:parse row data failed,column size is not match for table......

    一.异常现象截图  二.解决方式: 1.背景 早期的canal版本(<=1.0.24),在处理表结构的DDL变更时采用了一种简单的策略,在内存里维护了一个当前数据库内表结构的镜像(通过desc ...

  2. JVM的堆内存泄漏排查-性能测试

    JVM异常说明 https://testerhome.com/articles/24259 一文中已介绍了,JVM每个运行时区域--程序计数器 .Java虚拟机栈.本地方法栈.Java堆.方法区.直接 ...

  3. 入门大数据---HDFS-API

    第一步:创建一个新的项目 并导入需要的jar包 公共核心包 公共依赖包 hdfs核心包 hdfs依赖包 第二步:将Linux中hadoop的配置文件拷贝到项目的src目录下 第三步:配置windows ...

  4. stm32存储器映像和标准库中定义外设地址的方法

    结合存储器映像理解stm32标准库中定义外设地址的方法. stm32f103zet6是32位的.它所能访问的地址空间范围为2^32=4GB,把4GB分为8个block,分别为block0-block- ...

  5. plsql启动报 Using filter for all users can lead to poor perform

    首先,这个与Oracle配置无关,就是在使用pl/sql左侧树形目录时会看到非常多的和你当前工作无关的表,视图,序列等,导致打开速度慢. ​解决办法:Tools-->Object browser ...

  6. TypeScript学习——数组、元组、接口(2)

    数组 数组类型注解 const numberArr: (number | string)[] = [1, '2', 3]; //既可以是number 也可以是string const stringAr ...

  7. java语言进阶(六)_线程_同步

    第一章 多线程 想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,需要使用多进程或者多线程来解决. 1.1 并发与并行 并发:指两个或多个事件在同一个时间段内发生. 并行:指两个或多个事件 ...

  8. Web前端开发未来的六大趋势

    说起Web前端开发想必你一定不会陌生,因为现在的前端开发学习的培训机构也是层出不穷.下面济南优就业IT培训给大家总结出了未来Web前端开发的六大趋势从中可以大致看出来Web前端未来的发展前景. 趋势一 ...

  9. HBase2.0 meta信息丢失的修复方法

    在HBase入库日志中发现有一个表入库失败,检查HBase服务端后发现该表的meta信息丢失了: 而HDFS上的region还在: 而HBCK工具不支持HBase2.0版本,只好自己写一个修复工具.网 ...

  10. NumPy基础知识图谱

    所有内容整理自<利用Python进行数据分析>,使用MindMaster Pro 7.3制作,emmx格式,源文件已经上传Github,需要的同学转左上角自行下载.该图谱只是NumPy的基 ...