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)点都在起点左边 ...
随机推荐
- javascript常用对象方法
concat:连接产生一个新数组 [1,2].concat([3,4]) >> [1, 2, 3, 4] filter:返回符合条件的一个新数组 [1,2,3,4,5].filte ...
- 【转】unity3d 资源文件从MAX或者MAYA中导出的注意事项
转自游戏开发主席 1.首先,Unity3d 中,导出带动画的资源有2种导出方式可以选择: 1) 导出资源时,只导出一个文件,保留模型,骨骼和所有的动作帧(把所有的动作,比如idle,atta ...
- CVPR2018 关于视频目标跟踪(Object Tracking)的论文简要分析与总结
本文转自:https://blog.csdn.net/weixin_40645129/article/details/81173088 CVPR2018已公布关于视频目标跟踪的论文简要分析与总结 一, ...
- scatter注记词2
couch ranch bind ski extra bring note embrace tape they stick legend
- 3.配置HDFS HA
安装zookeeper下载zookeeper编辑zookeeper配置文件创建myid文件启动zookeeper配置HDFS HA配置手动HA配置自动HA启动HDFS HA namenode负责管理整 ...
- SGU 520 Fire in the Country(博弈+搜索)
Description This summer's heat wave and drought unleashed devastating wildfires all across the Earth ...
- $http.get(...).success is not a function 错误解决
$http.get(...).success is not a function 错误解决 1.6 新版本的AngularJs中用then和catch 代替了success和error,用PRomis ...
- 自测之Lesson14:多线程编程
题目:创建一个线程,并理清主线程结束时会发生什么. 代码: #include <stdio.h> #include <pthread.h> #include <unist ...
- 2017-2018-2 20172314 『Java程序设计』课程 结对编程练习_四则运算
相关过程截图 截图为我负责的部分关于计算的测试 关键代码解释 根据代码中的部分解释,这部分代码实现了结果的整数和分数的输出,如果算出的结果为一个真分数,就输出真分数的形式,如果结果为整数,就输出整数形 ...
- OSG学习:矩阵变换节点示例
#include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...