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的更多相关文章

  1. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  2. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  3. 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 ...

  4. 2019 wannafly winter camp day 3

    2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...

  5. 线段树优化建图(cf787d, 2019Wannafly Winter Camp Day7 Div1 E)

    线段树优化建图,用于区间到区间建边时降低空间复杂度 建立两颗线段树,一颗in, 代表进入这个区间,一颗out,代表从这个区间出去 in树从父亲向儿子建边,代表宏观进入整个区间,不向下寻找 out树从儿 ...

  6. 2020 CCPC-Wannafly Winter Camp Day2

    2020 CCPC-Wannafly Winter Camp Day2 A 托米的字符串 虽然每个子串出现的概率是相同的,但是同一长度的子串个数是不同的,所以要分别处理.计算出某一长度的情况下,元音字 ...

  7. CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...

    Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...

  8. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...

  9. 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)点都在起点左边 ...

随机推荐

  1. 82. Single Number [easy]

    Description Given 2*n + 1 numbers, every numbers occurs twice except one, find it. Example Given [1, ...

  2. python基本数据类型——集合

    集合 无序可变序列,集合中元素不允许重复,即每个元素都是唯一的 集合中的元素按照升序排列 # 创建集合 >>aset = set([0,2,4,5,7,2,3,5,9,0]) >&g ...

  3. 同台服务器 部署多个tomcat 需要做的修改

    需要修改以下加粗部分: 1:访问端口 8080->8081 2:shutdown 端口 8005->8015 3: AJP端口 8001->8010 <?xml version ...

  4. Android开发-API指南-<permission-tree>

    <permission-tree> 英文原文:http://developer.android.com/guide/topics/manifest/permission-tree-elem ...

  5. Java进阶知识点:协变与逆变

    一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那 ...

  6. solidity 十六进制字符串转十六进制bytes

    pragma solidity ^0.4.16; contract Metadata { // 十六进制字符串转换成bytes function hexStr2bytes(string data)re ...

  7. SIG蓝牙mesh笔记3_网络结构

    目录 3. Mesh Networking 3.1 Bearers 承载层 3.2 Network Layer 网络层 3.2.3 Address validity 地址有效性 3.2.4 Netwo ...

  8. 4.安装hive

      下载安装包并解压安装元数据库配置hive添加hvie环境变量修改hive-env.sh修改hive配置文件初始化metastore使用hive cli配置hivemestore配置hiveserv ...

  9. Python中的print

    Python 3.X的print 在Python 3.X中,print是一个内置函数,完整的声明形式如下: print([object, ...][, sep=' '][, end='\n'][, f ...

  10. Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...