Day1 Div2 场外链接

按题目顺序~

A 机器人 传送门

题意:有两条平行直线A、B,每条直线上有n个点,编号为1~n。在同一直线上,从a站点到b站点耗时为两点间的距离。存在m个特殊站点,只有在特殊站点才能到另一条直线上的对应编号站点,耗时K,且只有在特殊站点才能掉头,否则只能沿同一方向走。另外1号和n号站点为特殊站点。问从A直线上的s站点开始,经过r个给定的站点并回到原处最少需要的时间。

题解:我们可以分成两种大的情况讨论:

  1.给定的点都在A直线上,耗时等于路程。此时站点的分布有三种情况:s左右两边均存在、都在s左边、都在s右边。

  1)当给定的点在s左右两边都存在时,最少需要的时间为:s到 给定的最左边站点左边第一个特殊站点al(若它本身是特殊站点  站点al  就是该站点本身)距离的两倍(来回)+ s到 给定的最右边站点右边第一个特殊站点ar(若它本身是特殊站点  站点ar  就是该站点本身)距离的两倍(来回),即al到ar距离的两倍;

  2)当点都在s左边时,最少需要的时间为从s到 给定的最左边站点左边第一个特殊站点al(若它本身是特殊站点  站点al  就是该站点本身)距离的两倍(来回),此时把s也看成特殊点可以将s看做ar,那么最少需要的时间为al到ar距离的两倍;

  3)当点都在s左边时,同理,最少需要的时间为从s到 给定的最右边站点右边第一个特殊站点ar(若它本身是特殊站点  站点ar  就是该站点本身)距离的两倍(来回),此时可以将s看做al,那么最少需要的时间为al到ar距离的两倍;

  总的来说,当给定点都在A直线上时,最少需要的时间为为al到ar距离的两倍。al为给定的最左边的站点(若它是特殊站点)否则为其左边第一个特殊站点;ar同理。

  2.存在给定点在B直线上时,最少需要通过特殊点跨直线两次。我们可以看下图:

  

由图可知最小时间为:ar-al + br-bl + al-bl + br-ar + 2*k

为了防止都在一边的情况,在算al和ar时将s当做特殊站点计算,bl初始化为0,br初始化为n+1后面直接更新即可,不会影响bl和br的距离。

代码如下:

  1. #include<bits/stdc++.h>
  2. #define PI 3.141592653589793238462643383279
  3. using namespace std;
  4. typedef long long ll;
  5. const int N = 1e5+;
  6. const ll mod = ;
  7. struct node{
  8. int x, y;
  9. }a[N];
  10. int p[];
  11. int main(){
  12. int n,r,m,k,s;
  13. scanf("%d%d%d%d%d",&n,&r,&m,&k,&s);
  14. int flag=,al=s,ar=s,bl=n+,br=;
  15. for (int i=;i<r;i++){
  16. scanf("%d%d",&a[i].x,&a[i].y);
  17. if (a[i].y) flag=,bl=min(bl,a[i].x),br=max(br,a[i].x);
  18. al=min(al,a[i].x);
  19. ar=max(ar,a[i].x);
  20. }
  21. for (int i=;i<m;i++) scanf("%d",&p[i]);
  22. p[m]=,p[m+]=n;
  23. sort(p,p+m+);
  24. if (flag){
  25. for (int i=;;i++)
  26. if (p[i]>bl) {
  27. bl=p[i-];
  28. break;
  29. }
  30. for (int i=m+;;i--)
  31. if (p[i]<br){
  32. br=p[i+];
  33. break;
  34. }
  35. }
  36. p[m+]=s;
  37. sort(p,p+m+);
  38. for (int i=;;i++)
  39. if (p[i]>al){
  40. al=p[i-];
  41. break;
  42. }
  43. for (int i=m+;;i--)
  44. if (p[i]<ar){
  45. ar=p[i+];
  46. break;
  47. }
  48. ll ans=;
  49. if (!flag) ans=1ll*(ar-al)*;
  50. else {
  51. al=min(al,bl);
  52. ar=max(ar,br);
  53. ans=ar-al+br-bl+k*+bl-al+ar-br;
  54. }
  55. printf("%lld\n",ans);
  56. return ;
  57. }

B 吃豆豆  传送门

题意:有一个n行m列的棋盘,对于第i行第j列的格子,每过T[i][j]秒会出现一个糖果,糖果仅会在出现的那一秒存在,下一秒就会消失。假如你在第i行第j列格子上,你可以选择上下左右走一格,或者停在原地。现在指定初始位置和终点,问你从初始位置出发,初始时间为0秒,到终点的路上至少得到 C个糖果最少需要的时间。

题解:因为 n,m≤10,所以可以用搜索来做。从初始位置开始,直到到达终点且糖果数≥C时输出结果,程序终止。

代码如下:

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int N = +;
  5. bool vis[][][];
  6. int t[][],dp[][][];
  7. int d[][]={,,,,,-,-,,,};
  8. int main() {
  9. int n,m,c,xs,xt,ys,yt;
  10. scanf("%d%d%d",&n,&m,&c);
  11. for (int i=;i<=n;i++)
  12. for (int j=;j<=m;j++)
  13. scanf("%d",&t[i][j]);
  14. scanf("%d%d%d%d",&xs,&ys,&xt,&yt);
  15. memset(vis,false,sizeof(vis));
  16. vis[xs][ys][]=;
  17. for (int k=;;k++){
  18. for (int i=;i<=n;i++)
  19. for (int j=;j<=m;j++)
  20. if (vis[i][j][k-]) {
  21. for (int l=;l<;l++){
  22. int x=i+d[l][];
  23. int y=j+d[l][];
  24. if (x<||x>n||y<||y>m) continue;
  25. vis[x][y][k]=;
  26. if (k%t[x][y]==) dp[x][y][k]=max(dp[i][j][k-]+,dp[x][y][k]);
  27. else dp[x][y][k]=max(dp[x][y][k],dp[i][j][k-]);
  28. if (x==xt&&y==yt&&dp[x][y][k]>=c){
  29. printf("%d\n",k);
  30. return ;
  31. }
  32. }
  33. }
  34. }
  35. return ;
  36. }

C 拆拆拆数 传送门

题意:给你两个数A、B,把A拆成a1,a2...an,把B拆成b1,b2...bn,需满足:

  1.对所有i (1 ≤ i ≤ n),ai,bi ≥2 且 gcd(ai,bi) = 1;

  2.a1+a2+...+an=A , b1+b2+...+bn=B

  输出n最小的任意一组。

题解:当gcd(A,B)=1时,直接输出A,B;否则,拆成两个数就行了(待证),那么我们可以直接 i 从2开始暴力枚举,如果gcd(A-i,i)=1且gcd(i,B-i)=1输出即可。

代码如下:

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. int main() {
  5. int t;
  6. ll a,b;
  7. scanf("%d",&t);
  8. while(t--){
  9. scanf("%lld%lld",&a,&b);
  10. if (__gcd(a,b)==) {
  11. printf("1\n%lld %lld\n",a,b);
  12. continue;
  13. }
  14. for (ll i=;;i++){
  15. if (__gcd(a-i,i)==&&__gcd(i,b-i)==){
  16. printf("2\n%lld %lld\n%lld %lld\n",a-i,i,i,b-i);
  17. break;
  18. }
  19. }
  20. }
  21. return ;
  22. }

F 爬爬爬山 传送门

题意:有n座山,m条路。初始有k点体力,爬山过程中,所处海拔每上升1m,体力值-1,每下降1m,体力值+1。体力值不能为负,所以需要事先将山的高度降低,降低 l 米需要耗费l*l的价值,且每座山只能降一次。从1号山顶出发,所以1号山高度不能变。问:从1号山到n号山的总代价最小为多少:降低山消耗的价值+走过的路的总长度。

题解:显然每条路只会走一次,也就是说每座山只会走这一条路到达且只会到达一次,所以我们在给两座山加路的时候可以把需要降低山的价值加到路的权值里面。稀疏图+最短路即可。这里我用的链式向前星建图。

代码如下:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define pr pair<ll,int>
  4. #define mp make_pair
  5. using namespace std;
  6. const int N = 1e5+;
  7. const ll INF = 0x3f3f3f3f;
  8. struct node
  9. {
  10. int to,next;
  11. ll w;
  12. }e[N<<];
  13. ll h[N],dis[N];
  14. int head[N],cnt;
  15. bool vis[N];
  16.  
  17. void init()
  18. {
  19. cnt=;
  20. memset(head,-,sizeof(head));
  21. }
  22.  
  23. void add(int u,int v,ll w)
  24. {
  25. e[cnt].to=v;
  26. e[cnt].w=w;
  27. e[cnt].next=head[u];
  28. head[u]=cnt++;
  29. }
  30.  
  31. void dij(int n)
  32. {
  33. memset(vis,false,sizeof(vis));
  34. memset(dis,INF,sizeof(dis));
  35. priority_queue <pr> q;
  36. dis[] = ;
  37. q.push(mp(,));
  38. while(!q.empty())
  39. {
  40. int x = q.top().second;
  41. q.pop();
  42. for (int i = head[x]; ~i; i=e[i].next)
  43. {
  44. if (dis[e[i].to]>dis[x]+e[i].w)
  45. {
  46. dis[e[i].to]=dis[x]+e[i].w;
  47. q.push(mp(-dis[e[i].to],e[i].to));
  48. }
  49. }
  50. }
  51. printf("%lld\n",dis[n]);
  52. }
  53.  
  54. int main()
  55. {
  56. int n,m,u,v;
  57. ll k,w;
  58. init();
  59. scanf("%d%d%lld",&n,&m,&k);
  60. for (int i=;i<=n;i++)
  61. scanf("%lld",&h[i]);
  62. k+=h[];
  63. for (int i=;i<m;i++)
  64. {
  65. scanf("%d%d%lld",&u,&v,&w);
  66. if (h[u]-k>) add(v,u,w+(h[u]-k)*(h[u]-k));
  67. else add(v,u,w);
  68. if (h[v]-k>) add(u,v,w+(h[v]-k)*(h[v]-k));
  69. else add(u,v,w);
  70. }
  71. dij(n);
  72. return ;
  73. }

J 夺宝奇兵 传送门

题意:有n个居民,他们一共有m件宝物,对于第i件宝物,wls可以花费a1的金币买过来,问wls最少要准备多少金币,才能使他成为宝物最多的(>其他任何人的)。

题解:因为n,m≤1000,数据量比较小,所以我们可以枚举要买的宝物件数,先把比这个数量多的居民的宝物按价格从低到高买,若≤要买的数量,则再每买过的宝物里按价格从低到高买,更新答案。

代码如下:

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int N = +;
  5. struct node
  6. {
  7. ll a;
  8. int c,pos;
  9. }b[N],c[N];
  10. bool vis[N];
  11. bool cmp1(node i,node j)
  12. {
  13. return i.a<j.a;
  14. }
  15. bool cmp2(node i,node j)
  16. {
  17. if (i.c == j.c)
  18. return i.a>j.a;
  19. return i.c<j.c;
  20. }
  21. int main()
  22. {
  23. ll x;
  24. int n,m,y;
  25. scanf("%d%d",&n,&m);
  26. for (int i=;i<=m;i++)
  27. {
  28. scanf("%lld%d",&x,&y);
  29. b[i].a=x;
  30. b[i].c=y;
  31. b[i].pos=i;
  32. c[i]=b[i];
  33. }
  34. sort(b+,b++m,cmp1);
  35. sort(c+,c++m,cmp2);
  36. ll mmax=1e17;
  37. for (int need=;need<=m;need++)
  38. {
  39. ll ans=;
  40. int have=,k=;
  41. memset(vis,false,sizeof(vis));
  42. for (int j=;j<=m;j++)
  43. {
  44. if (c[j-].c != c[j].c) k=;
  45. else k++;
  46. if (k>need)
  47. {
  48. have++;
  49. ans+=c[j].a;
  50. vis[c[j].pos]=true;
  51. }
  52. }
  53. if (have<=need)
  54. {
  55. for (int j=;j<=m;j++)
  56. {
  57. if (!vis[b[j].pos])
  58. {
  59. have++;
  60. vis[b[j].pos]=true;
  61. ans+=b[j].a;
  62. if (have>need) break;
  63. }
  64. }
  65. }
  66. if (have>need)
  67. mmax=min(mmax,ans);
  68. }
  69. printf("%lld\n",mmax);
  70. return ;
  71. }

其他题待补。。。

CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...的更多相关文章

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

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

  2. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  3. 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)

    题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...

  4. CCPC Wannafly Winter Camp Div2 部分题解

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

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

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

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

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

    Replay Dup4: 要是不挂机,再多仔细想想就好了 J确实自闭好久,一直在想正确性,最后数据错了,喵喵喵? 还是要保证充足的休息啊,中间睡了一小会儿,也不知道睡了多久,醒来他们就又过了一道 要发 ...

  8. Comet OJ CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) F.爬爬爬山-最短路(Dijkstra)(两个板子)+思维(mdzz...) zhixincode

    爬爬爬山 已经提交 已经通过 9.83% Total Submission:417 Total Accepted:41 题目描述 爬山是wlswls最喜欢的活动之一. 在一个神奇的世界里,一共有nn座 ...

  9. CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) A,B,C,E,F,I,J

    https://www.zhixincode.com/contest/7/problems A题 分类讨论 当B有点需要经过时 穿梭的花费肯定为2*k,也可以发现,我们要找到包含所有需要经过的点(不含 ...

随机推荐

  1. Spring MVC 解决 Could not write JSON: No serializer found for class java.lang.Object

    Spring MVC 解决 Could not write JSON: No serializer found for class java.lang.Object 资料参考:http://stack ...

  2. sleep usleep nanosleep alarm setitimer使用

    sleep使用的是alarm之类的定时器,定时器是使得进程被挂起,使进程处于就绪的状态. signal+alarm定时器 alarm参数的类型为uint, 并且不能填0 #include <st ...

  3. 利用sort对数字排序

    sort,可排序字符串,按照ASCII码排序. 但也可以穿一个比较函数,实现比较数组内容,排序数组的功能. var arr = [40, 32, 45, 89, 93, 0, 46, 74]; var ...

  4. H3C 传递信息

  5. python基础十四之匿名函数

    匿名函数 处理简单问题的简化函数,关键字lambda. # 格式:函数名 = lambda 参数:返回值 anonymity = lambda s: s ** 0.5 print(anonymity( ...

  6. H3C IEEE EUI-64格式

  7. vue项目导入excel单列导入

    先安装 xlsx.js, 然后引入 import XLSX from 'xlsx'; 代码 <form> <span> <textarea name="cont ...

  8. vue移动端图片上传压缩

    上传压缩方法 import {api} from '../../api/api.js'; import axios from 'axios'; export function imgPreview ( ...

  9. CodeForce - 1189 D1. Add on a Tree (思维题)

    Note that this is the first problem of the two similar problems. You can hack this problem only if y ...

  10. 由Request Method:OPTIONS初窥CORS

    刚接触前端的时候,以为HTTP的Request Method只有GET与POST两种,后来才了解到,原来还有HEAD.PUT.DELETE.OPTIONS…… 目前的工作中,HEAD.PUT.DELE ...