CCPC-Winter Camp div2 day1
A:机器人
传送门:https://www.zhixincode.com/contest/1/problem/A
题意:地图是由A、B两根线组成的,机器人一开始是在A线上的S点,他初始时可以选择任意方向前进,但是除非碰见特殊点,否则是不能转弯的,他有r个必须经过的点分布在A线和B线上,有m个特殊点可以进行转向,这些特殊点对称分布在A、B两条线上,并且1,n这两个点也是特殊点,也就是说机器人一定可以转弯,A、B之间的距离是K,求机器人经过所有的必须经过的点后回到起点。
题解:画图.jpg
画图我们可以知道,我们要想经过所有的特殊点,只需要讨论两种情况,
一种是,B线上没有,那么只在A上走,
一种是B线上 有,那么我们只需要找到A的最左端,B的最左端、A的最右端、B的最右段的转折点即可,这样就可以保证走了一圈,肯定将所有的特殊点都经过了,并且路径最短
我们要特殊考虑一下如果只在起点S的左端有需要经过的点或者只在起点S右端怎么办呢
我们画图可以知道
他是这样走的,所以我们需要计算出
①A、B的区间长lena,lenb
②A、B的区间长之差len2
这样就可以求出只在一边的情况
实际上,如果不在一边的话,A、B的区间长之差是0,所以这些都是可以分在同一种情况的,只需要对(0,len2)取一个max即可
代码如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = ;
const int maxn = 2e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int a[maxn], b[maxn];
int flag = ;
vector<int> p;
int n, r, m, k, s;
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
scanf("%d%d%d%d%d", &n, &r, &m, &k, &s);
int tot1 = , tot2 = ;
for(int i = ; i < r; i++) {
int x, tmp;
scanf("%d%d", &x, &tmp);
if(tmp == ) {
a[tot1++] = x;
} else {
b[tot2++] = x;
}
}
for(int i = ; i < m; i++) {
int x;
scanf("%d", &x);
p.push_back(x);
}
p.push_back();
p.push_back(n);
sort(a, a + tot1); sort(b, b + tot2);
sort(p.begin(), p.end());
int al = n, ar = , bl = n, br = ;
for(int i = ; i < tot2; i++) {
bl = min(bl, *(upper_bound(p.begin(), p.end(), b[i] ) - ));
br = max(br, *lower_bound(p.begin(), p.end(), b[i]));
}
p.push_back(s);
sort(p.begin(), p.end());
for(int i = ; i < tot1; i++) {
al = min(al, *(upper_bound(p.begin(), p.end(), a[i] ) - ));
ar = max(ar, *lower_bound(p.begin(), p.end(), a[i]));
}
al = min(al, bl), ar = max(ar, br);
//cout<<al<<" "<<ar<<endl; if(tot2 == ) {
// cout << (ar - al) * 2 << endl;
//防止只在一边的情况
cout << (max(, al - s) + max(, s - ar) + ar - al) * << endl; //s到a+a区间长*2
} else {
//防止只在一边的情况
cout << (max(, al - s) + max(, s - ar)) * + //s到a
ar - al + br - bl + //ab区间长
bl - al + ar - br + //a超出b
k * << endl; //跨越 }
return ;
}
B:吃豆豆
传送门:https://www.zhixincode.com/contest/1/problem/B
题意:有一个n*m的格子图,每个格子有一个时间戳t[i][j],代表这个格子每过时间t[i][j]会有一颗糖果,如果人刚好站在这个地方,人就可以得到这个糖果,人的起始位置是sx,sy,他需要移动到终点ex,ey处,问他至少吃C颗糖果所需要的最少的时间是多少
题解:我们考虑,图十分的小,最大是10*10,t[i][j]小于10,最多要吃 1018颗糖果,那么我即使呆在一个位置不动,我最多也只需要10180秒吃掉1018颗糖果,我们很显然可以暴力得到所有的状态的,就和dp联系起来了
我们定义dp[x][y][k]为在x,y这个位置,花费k的时间得到的糖果数量最多是多少
那么转移方程就是:
emmm奇妙的转移,不太好形容,有点bfs的意思在里面吧,还是很容易看懂的。如果这个位置的时间刚好取模当前位置的时间戳为0的话,那么由上一步转来的糖果数就可以+1
代码如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = ;
const int maxn = 2e5 + ;
const double pi = acos(-);
const int INF = 0x3f3f3f3f; int dx[] = {, , -, , };
int dy[] = {, , , -, };
int dp[][][];//在i,j这个点,花费k的时间,可以得到的糖果
int mp[][];
int sx, sy, ex, ey;
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int n, m, C;
scanf("%d%d%d", &n, &m, &C);
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
scanf("%d", &mp[i][j]);
}
}
memset(dp, -INF, sizeof(dp));
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
dp[sx][sy][] = ;
for(int i = ; i <= ; i++) {
for(int x = ; x <= n; x++) {
for(int y = ; y <= m; y++) {
for(int j = ; j < ; j++) {
int nx = x + dx[j];
int ny = y + dy[j];
if(nx <= || nx > n || ny <= || ny > m
|| dp[nx][ny][i - ] == -INF) continue;
if(i % mp[x][y] == ) {
dp[x][y][i] = max(dp[x][y][i], dp[nx][ny][i - ] + );
} else {
dp[x][y][i] = max(dp[x][y][i], dp[nx][ny][i - ]);
}
}
}
}
}
int ans = INF;
for(int i = ; i <= ; i++) {
if(dp[ex][ey][i] >= C) {
ans = i;
break;
}
}
cout << ans << endl;
return ;
}
C:拆拆拆数
传送门:https://www.zhixincode.com/contest/1/problem/C?problem_id=14
题意:将a、b分成ai和bi使得ai和bi互质并且ai、bi都要大于2
题解:两个相邻的数一定互质,那么我们就可以从a-2和b-2开始枚举,一定可以找到在10以内使得a-i与b-j互质(我也不知道我瞎说的)
代码如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = ;
const int maxn = 2e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
long long gcd(long long a, long long b) {
return b ? gcd(b, a % b) : a; }
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
scanf("%d", &T);
while(T--) {
LL a, b;
scanf("%lld%lld", &a, &b);
int flag = ;
if(gcd(a,b)==){
printf("1\n%lld %lld\n",a,b);
continue;
}
for(int i = ; i <= ; i++) {
if(flag) {
for(int j = ; j <= ; j++) {
if(gcd(i, j) == && gcd(a - i, b - j) == ) {
printf("2\n%d %d\n%lld %lld\n", i, j, a - i, b - j);
flag=;
break;
}
}
} else {
break;
}
}
}
return ;
}
F:爬爬爬山
传送门:https://www.zhixincode.com/contest/1/problem/F?problem_id=17
题意:上山会损耗体力值,下山会增加体力值,我们这样想,我们假设一开始就站在了h[1]+k这样的高度,如果前面的山比我还要高,我是一定要把前面的山给砍掉的,如果比我矮,我还是最后要爬上h[1]+k这样的高度,一加一减其实就抵消了,所以我们关心的就是高度高于h[1]+k的山峰,然后建立双向边跑最短路即可,起点是1,终点是n
代码如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = ;
const int maxn = 4e5 + ;
const double pi = acos(-);
const LL INF = 1e18;
LL h[maxn];
struct EDGE {
int v, nxt;
LL w;
} edge[maxn];
int head[maxn];
int tot;
void add_edge(int u, int v, LL w) {
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot++;
}
struct node {
int s, dis;
node (int _s, int _dis) {
s = _s;
dis = _dis;
};
};
LL dis[maxn];
int vis[maxn];
void dijkstra(int st) {
memset(dis, 0x3f, sizeof(dis));
memset(vis, , sizeof(vis));
priority_queue<pLL> q;
dis[st] = ;
q.push(make_pair(, st));
while(!q.empty()) {
int x = q.top().second;
q.pop();
if(vis[x]) continue;
vis[x] = ;
for(int i = head[x]; i != -; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] > dis[x] + edge[i].w) {
dis[v] = dis[x] + edge[i].w;
q.push(make_pair(-dis[v], v));
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int n, m;
LL k;
scanf("%d%d%lld", &n, &m, &k);
for(int i = ; i <= n; i++) {
scanf("%lld", &h[i]);
}
memset(head, -, sizeof(head));
tot = ;
k += h[];
for(int i = ; i < m; i++) {
int u, v;
LL w;
scanf("%d%d%lld", &u, &v, &w);
if(h[v] >= k) add_edge(u, v, w + (h[v] - k) * (h[v] - k));
else add_edge(u, v, w);
if(h[u] >= k) add_edge(v, u, w + (h[u] - k) * (h[u] - k));
else add_edge(v, u, w);
}
dijkstra();
printf("%lld\n", dis[n]);
return ;
}
J:夺宝奇兵
传送门:https://www.zhixincode.com/contest/1/problem/J?problem_id=21
题意:我们可以买别人的东西,最终要使得我们的东西是最多的,问最小的花费是多少
题解:要想使我们的东西最多,我们的东西应该是比当前拥有最多物品的人的物品还多,所以我们可以枚举我们需要买的物品数量,然后将其余所有人的物品数量降到这个数量级以内,如果将所有人的物品降到这个数量级以内还是没有让我的物品到达这个数量时,我就将物品从便宜的开始买,一直买到我的物品的数量达到我规定的这个量级位置,枚举时每次更新使得所有人达到当前量级以下需要花费的最小值,更新答案
代码如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = ;
const int maxn = 2e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int n, m;
vector<int> vec[maxn];
LL check(int cnt) {
vector<int> res;
LL tmp = ;
int cnt1 = ;
for(int i = ; i <= n; i++) {
int sz=vec[i].size();
for(int j = ; j < sz; j++) {
if(j < sz-(cnt-)) {
tmp += vec[i][j];
cnt1++;
} else {
res.push_back(vec[i][j]);
}
}
}
// cout<<res.size()<<endl;
sort(res.begin(), res.end());
for(int i = ; i < res.size() && cnt1 < cnt; i++) {
tmp += res[i];
cnt1++;
}
return tmp;
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i++) {
int a, c;
scanf("%d%d", &a, &c);
vec[c].push_back(a);
}
for(int i = ; i <= n; i++) {
sort(vec[i].begin(), vec[i].end());
}
LL ans = INF;
for(int i = ; i <= m; i++) {
ans = min(ans, check(i));
}
cout << ans << endl;
return ;
}
CCPC-Winter Camp div2 day1的更多相关文章
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- 2019 wannafly winter camp
2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...
- 2019 wannafly winter camp day 3
2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...
- 线段树优化建图(cf787d, 2019Wannafly Winter Camp Day7 Div1 E)
线段树优化建图,用于区间到区间建边时降低空间复杂度 建立两颗线段树,一颗in, 代表进入这个区间,一颗out,代表从这个区间出去 in树从父亲向儿子建边,代表宏观进入整个区间,不向下寻找 out树从儿 ...
- 2020 CCPC-Wannafly Winter Camp Day2
2020 CCPC-Wannafly Winter Camp Day2 A 托米的字符串 虽然每个子串出现的概率是相同的,但是同一长度的子串个数是不同的,所以要分别处理.计算出某一长度的情况下,元音字 ...
- CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...
Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...
- CCPC-Wannafly Winter Camp Day1 (Div2, onsite) A B C E F I J
A 机器人 链接:https://www.cometoj.com/contest/7/problem/A?problem_id=92 思路: 分两大类讨论: 1. B区没有点: (1)点都在起点左边 ...
随机推荐
- 学习笔记,99乘法表,嵌套while循环
line = 0 #定义外循环初变量 while line < 9: #外循环判断语句 line += 1 #改变外循环初变量,避免陷入死循环 row = 0 #定义内循环初变量 while r ...
- 【zabbix 监控】第二章 安装测试被监控主机
客户端安装测试 一.准备两台被监控主机,分别做如下操作: web129:192.168.19.129 web130:192.168.19.130 [root@web129 ~]#yum -y inst ...
- 由一个hash字符串生成多个子hash字符串
通过存储一个head hash,然后把子hash放到网络中 当然,也可以像默克尔树那样的,生成多级的子hash ,可以通过规则配置不同的hash 生成方式.倒置的默克尔树 我有一个文件,然后我把她分隔 ...
- idea clion编译器
RNMV64P0LA-eyJsaWNlbnNlSWQiOiJSTk1WNjRQMExBIiwibGljZW5zZWVOYW1lIjoiY24gdHUiLCJhc3NpZ25lZU5hbWUiOiIiL ...
- kvm网络虚拟化
网络虚拟化是虚拟化技术中最复杂的部分,学习难度最大. 但因为网络是虚拟化中非常重要的资源,所以再硬的骨头也必须要把它啃下来. 为了让大家对虚拟化网络的复杂程度有一个直观的认识,请看下图 这是 Open ...
- POJ 1655 Balancing Act(求树的重心)
Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any nod ...
- Windows Phone编程回顾
前言 已有一年多没有碰WP相关的开发了. 近期经常看博客园的文章, 发现开发WP应用的同学很多, 其中博问频道关于"WPF", "C#", "WP8& ...
- LintCode-376.二叉树的路径和
二叉树的路径和 给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径. 一个有效的路径,指的是从根节点到叶节点的路径. 样例 给定一个二叉树,和 目标值 = 5: 返回: [ ...
- 最近面试js部分试题总结
二,JavaScript面试题总结 1,首先是数组去重算法:给一个数组,去掉重复值 (function() { var arr = [1, 2, 3, 3, 4, ]; function unique ...
- 火狐浏览器(FireFox)安装Flash插件失败处理方法
最近不知道怎么了,总是嫌弃IE,可能是被网络流量监测的网址给搞得了,弄了火狐浏览器,也安装了猎豹,这里不对浏览器做评价 好多朋友安装好火狐(FireFox)的时候发现之前不是有装IE的Flash播放插 ...