DAY 1        2019.4.28


例题1

题解:

例题2

题解:

例题3

题解:

vis[ ]判断是否为素数,pri[ ]储存素数

例题4

题解:

例题5

题解:

PS: i  <  1<<n        i<2^n

(1<<j)& i      如果2^j最后一位和 i 相同,返回1

例题6

判回文数是N√N,素数NlogN

枚举:

1.从起点开始向四个方向扩展

2.到一个点卡死,删除栈中的位置,回到前一步继续搜

3.找到一种解

4.这也是一个解

PS:DFS不会死循环,走完一个方向就会走其他方向

例题:

题解:

实际上就是寻找是否存在路径小于等于T

VIS[ ][ ]判断这个坐标是否走过

PS:

1.DFS使用一遍之后清空所影响数据

2.命名变量不要重名

  每组数据开始之前ans要回归初始值

[代码]:

  1. #include<cstdio>
  2. #include<algorithm>
  3.  
  4. #define N 15
  5.  
  6. using namespace std;
  7.  
  8. int i,j,m,n,p,k,vis[N][N],tmp,T,ans=,tot;
  9.  
  10. char c[N][N];
  11.  
  12. pair<int,int> Ans[N*N];
  13.  
  14. const int X[]={,,-,};
  15. const int Y[]={-,,,};
  16.  
  17. int check(int x,int y) //是否合法
  18. {
  19. if (x<=||y<=||x>n||y>n) return ;
  20. if (vis[x][y]) return ;
  21. if (c[x][y]=='#') return ;
  22. return ;
  23. }
  24.  
  25. void dfs(int x,int y)
  26. {
  27. if (c[x][y]=='E')
  28. {
  29. ans=min(ans,tot);
  30. return;
  31. }
  32. vis[x][y]=;
  33. Ans[++tot]=make_pair(x,y);
  34. int i; //辅助变量,开在里面
  35. for (i=;i<;++i)
  36. if (check(x+X[i],y+Y[i]))
  37. dfs(x+X[i],y+Y[i]);
  38. --tot;
  39. vis[x][y]=;
  40. }
  41.  
  42. void Main()
  43. {
  44. ans=(int)1e9;
  45. scanf("%d%d",&n,&T);
  46. for (i=;i<=n;++i) scanf("%s",c[i]+);
  47. for (i=;i<=n;++i)
  48. for (j=;j<=n;++j)
  49. if (c[i][j]=='S') dfs(i,j);
  50. printf(ans<=T?"YES\n":"NO\n");
  51. }
  52.  
  53. int main()
  54. {
  55. int T;
  56. scanf("%d",&T);
  57. for (;T--;) Main(); //用一个过程实现多组数据,模块化
  58. }

1.沿四个方向扩展

2.起点出发,四周搜,可以走,加队列

3.维护每个点距离起点的最短距离

[代码]:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<ctime>
  6. #include<cmath>
  7. #include<map>
  8. #include<set>
  9. #include<bitset>
  10. #include<vector>
  11.  
  12. #define ls (t<<1)
  13. #define rs ((t<<1)|1)
  14.  
  15. #define N 15
  16. #define M 200005
  17. #define K 17
  18.  
  19. #define pb push_back
  20. #define fi first
  21. #define se second
  22. #define mk make_pair
  23.  
  24. using namespace std;
  25.  
  26. int i,j,n,m,Time;
  27.  
  28. char c[N][N];
  29.  
  30. int vis[N][N];
  31.  
  32. pair<int,int> Q[N*N];
  33.  
  34. const int x[]={-,,,};
  35. const int y[]={,,-,};
  36.  
  37. int check(int x,int y)
  38. {
  39. if (x<||y<||x>n||y>n) return ;
  40. if (c[x][y]=='#') return ;
  41. if (vis[x][y]!=-) return ;
  42. return ;
  43. }
  44.  
  45. int bfs(int sx,int sy)
  46. {
  47. int i,l,r;
  48. memset(vis,-,sizeof(vis));
  49. Q[r=]=mk(sx,sy); vis[sx][sy]=;
  50. for (l=;l<=r;++l)
  51. {
  52. int ax=Q[l].fi,ay=Q[l].se;
  53. if (c[ax][ay]=='E')
  54. {
  55. if (vis[ax][ay]<=Time) return ;
  56. return ;
  57. }
  58. for (i=;i<;++i)
  59. if (check(ax+x[i],ay+y[i]))
  60. {
  61. Q[++r]=mk(ax+x[i],ay+y[i]);
  62. vis[ax+x[i]][ay+y[i]]=vis[ax][ay]+;
  63. }
  64. }
  65. return ;
  66. }
  67.  
  68. int main()
  69. {
  70. int T; scanf("%d",&T);
  71. for (;T--;)
  72. {
  73. scanf("%d%d",&n,&Time);
  74. for (i=;i<=n;++i) scanf("%s",c[i]+);
  75. for (i=;i<=n;++i)
  76. for (j=;j<=n;++j) if (c[i][j]=='S') {
  77. if (bfs(i,j)) puts("YES"); else puts("NO");
  78. }
  79. }
  80. }

DFS  先扩展,不行就回头

    存储空间小

BFS  一般是求最短路径

    全部走,所有路径集合,空间大

    为所有可能的结果开数据

Pair 数组相当于一个结构体,int int两个元素,存横纵坐标

Vector

Vector可以用来存图存数据

可以自己定义类型

相当于开了N个int数组,长度可以很长

其实相当于开了一个二维数组

相当于在数组第y行最后加入一个x

在数组第x行最后加入一个y

每一行数组表示该点可以到达的点(也就是这两个点之间联通)

弹出

[代码]:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<ctime>
  6. #include<cmath>
  7. #include<map>
  8. #include<set>
  9. #include<bitset>
  10. #include<vector>
  11.  
  12. #define ls (t<<1)
  13. #define rs ((t<<1)|1)
  14.  
  15. #define N 100005
  16. #define M 200005
  17. #define K 17
  18.  
  19. #define pb push_back
  20. #define fi first
  21. #define se second
  22. #define mk make_pair
  23.  
  24. using namespace std;
  25.  
  26. vector<int>v[N];
  27.  
  28. int i,j,m,n,p,k,vis[N],Q[N],ans;
  29.  
  30. void bfs(int x)
  31. {
  32. int l,r;
  33. Q[r=]=x;
  34. vis[x]=;
  35. for (l=;l<=r;++l)
  36. {
  37. int p=Q[l];
  38. for (i=;i<(int)v[p].size();++i) //遍历所有出边
  39. {
  40. int k=v[p][i]; //vector类型其实相当于二维数组
  41. if (vis[k]) continue;
  42. vis[k]=;
  43. Q[++r]=k;
  44. }
  45. }
  46. }
  47.  
  48. int main()
  49. {
  50. scanf("%d%d",&n,&m);
  51. for (i=;i<=m;++i)
  52. {
  53. int x,y;
  54. scanf("%d%d",&x,&y);
  55. v[y].push_back(x);
  56. v[x].push_back(y);
  57. }
  58. for (i=;i<=n;++i)
  59. if (!vis[i])
  60. {
  61. bfs(i);
  62. ans++;
  63. }
  64.  
  65. cout<<ans;
  66.  
  67. }

PS:

k=奇数  =>  k^=1为k=k-1

k=偶数  =>  k^=1为k=k+1

[代码]:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<ctime>
  6. #include<cmath>
  7. #include<map>
  8. #include<set>
  9. #include<bitset>
  10. #include<vector>
  11.  
  12. #define ls (t<<1)
  13. #define rs ((t<<1)|1)
  14.  
  15. #define N 1005
  16. #define M 200005
  17. #define K 17
  18.  
  19. #define pb push_back
  20. #define fi first
  21. #define se second
  22. #define mk make_pair
  23.  
  24. using namespace std;
  25.  
  26. int i,j,m,n,p,k,r[];
  27.  
  28. int vis[N][N];
  29.  
  30. pair<int,int> Q[][N*N];
  31.  
  32. char c[N][N];
  33.  
  34. const int X[]={-,,,};
  35. const int Y[]={,,-,};
  36.  
  37. int check(int x,int y)
  38. {
  39. if (x<=||y<=||x>n||y>m) return ;
  40. if (vis[x][y]) return ;
  41. return ;
  42. }
  43.  
  44. void bfs(int x,int y)
  45. {
  46. int i,l,now=;
  47. Q[][r[]=]=make_pair(x,y);
  48. memset(vis,-,sizeof(vis));
  49. vis[x][y]=;
  50. for (;;) //死循环
  51. {
  52. now^=;
  53. if (!r[now]) return;
  54. for (l=;l<=r[now];++l)
  55. {
  56. int ax=Q[now][r[now]].first,ay=Q[now][r[now]].second;
  57. for (i=;i<;++i)
  58. if (check(ax+X[i],ay+Y[i]))
  59. {
  60. int ck=c[ax+X[i]][ay+Y[i]]=='#';
  61. if (!ck) //如果可以走,加入当前队列
  62. {
  63. vis[ax+X[i]][ay+Y[i]]=vis[ax][ay];
  64. Q[now][++r[now]]=make_pair(ax+X[i],ay+Y[i]);
  65. }
  66. else // 否则加入暂时先不扩展的队列
  67. {
  68. vis[ax+X[i]][ay+Y[i]]=vis[ax][ay]+;
  69. Q[now^][++r[now^]]=make_pair(ax+X[i],ay+Y[i]);
  70. }
  71. } // 维护两个不同的队列
  72. }
  73. }
  74. }
  75.  
  76. int main()
  77. {
  78. scanf("%d%d",&n,&m);
  79. for (i=;i<=n;++i) scanf("%s",c[i]+);
  80. for (i=;i<=n;++i)
  81. for (j=;j<=m;++j)
  82. if (c[i][j]=='S') bfs(i,j);
  83. for (i=;i<=n;++i)
  84. for (j=;j<=m;++j)
  85. if (c[i][j]=='E') printf("%d\n",vis[i][j]);
  86. }

能BFS就BFS,否则考虑DFS

K表示有没有用过正方形

Id表示高度,不可以超边界

代码加了剪枝

一个固体块,确定一个小块的位置,其余小块的位置就可以确定,整个固体块也就确定了

比如,( a, b ) 第一块固体块的左上角方块坐标

( c , d ) 第二块固体块的左上角方块坐标

( e , f ) 第三块固体块的左上角方块坐标

然后根据相对位置推出其余小块的坐标

六维

比如,( 0 , 0 ) 第一块固体块的左上角方块坐标

( c , d ) 第二块固体块的左上角方块坐标

( e , f ) 第三块固体块的左上角方块坐标

然后根据相对位置推出其余小块的坐标

移动的话要根据相对位置

状态数404

一个四维状态


化简一下

ans=∑(Ai – Bi)*j+Bi*n- Ai

Ai – Bi越小越靠后

∑Bi(ti-T)=0

我们会得到一半正的一半负的

正:∑Bi,ti-T

负:∑Bi,ti-T

若|正|<|负|

那么正的就全取,负的有一部分为之抵消,至于未能抵消掉的,就直接不开此水龙头

[代码]:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4.  
  5. #define N 300005
  6.  
  7. using namespace std;
  8.  
  9. int a[N],t[N],i,j,m,n,p,k,id[N],ID[N],sum[N],T;
  10.  
  11. double ans;
  12.  
  13. int cmp(int x,int y)
  14. {
  15. return sum[x]<sum[y];
  16. }
  17.  
  18. int main()
  19. {
  20. scanf("%d%d",&n,&T);
  21. for (i=;i<=n;++i)
  22. {
  23. scanf("%d",&a[i]);
  24. }
  25. for (i=;i<=n;++i) scanf("%d",&t[i]);
  26. for (i=;i<=n;++i)
  27. {
  28. if (t[i]==T) ans+=a[i];
  29. else if (t[i]<T) id[++id[]]=i,sum[i]=T-t[i];
  30. else ID[++ID[]]=i,sum[i]=t[i]-T;
  31. }
  32. sort(id+,id+id[]+,cmp);
  33. sort(ID+,ID+ID[]+,cmp);
  34. long long suma=,sumb=;
  35. for (i=;i<=id[];++i)
  36. suma+=1ll*sum[id[i]]*a[id[i]];
  37. for (i=;i<=ID[];++i)
  38. sumb+=1ll*sum[ID[i]]*a[ID[i]];
  39. if (suma<sumb)
  40. {
  41. swap(suma,sumb);
  42. for (i=;i<=n;++i) swap(ID[i],id[i]);
  43. }
  44. for (i=;i<=ID[];++i) ans+=a[ID[i]];
  45. for (i=;i<=id[];++i)
  46. if (1ll*sum[id[i]]*a[id[i]]>=sumb)
  47. {
  48. ans+=.*sumb/sum[id[i]];
  49. break;
  50. }
  51. else
  52. {
  53. ans+=a[id[i]];
  54. sumb-=1ll*sum[id[i]]*a[id[i]];
  55. }
  56. printf("%.10lf\n",ans);
  57. }


示例:

【代码】:

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int a[],n,m,l,r,mid,x;
  6.  
  7. int main()
  8. {
  9. scanf("%d%d",&n,&x);
  10.  
  11. for(int i=;i<=n;++i)
  12. scanf("%d",&a[i]);
  13.  
  14. sort(a+,a+n+); //保证递增
  15.  
  16. int l=,r=n+,mid=; //初始化
  17.  
  18. while((l+r)>>!=mid) //如果还可以继续二分
  19. {
  20. mid=(l+r)>>;
  21. if(x>=a[mid]) l=mid;
  22. else r=mid;
  23. }
  24.  
  25. cout<<l;
  26. //找到x在序列中排第几
  27. }

预处理相邻距离

距离最远的那次尽可能短

使用mid的跳跃是否合法

【代码】:

  1. #iclude<bits/stdc++.h>
  2.  
  3. #define N 300005
  4.  
  5. using namespace std;
  6.  
  7. int i,j,m,n,p,k,a[N],x;
  8.  
  9. int check(int x)
  10. {
  11. int i,cnt=;
  12. for (i=;i<=n;++i) if (a[i]-a[i-]>x) return ; //跳不过去
  13. for (i=;i<n;)
  14. {
  15. for (j=i;j<=n&&a[j]-a[i]<=x;++j);
  16. ++cnt;
  17. i=j-;
  18. }
  19. if (cnt<=m) return ;
  20. return ;
  21. }
  22.  
  23. int main()
  24. {
  25. scanf("%d%d",&n,&m);
  26. for (i=;i<=n;++i) scanf("%d",&a[i]);
  27. sort(a+,a+n+);
  28. int l=,r=(int)1e9,mid=; //因为没有给定右端点
  29. while ((l+r)>>!=mid)
  30. {
  31. mid=(l+r)>>;
  32. if (check(mid)) r=mid;
  33. else l=mid;
  34. }
  35. printf("%d\n",r);
  36. }

P2678 跳石头

这也是个二分题,好像和刚才的不大一样

所以应该是:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4.  
  5. #define N 300005
  6.  
  7. using namespace std;
  8.  
  9. int a[N],t[N],i,j,m,n,p,k,id[N],ID[N],sum[N],T;
  10.  
  11. double ans;
  12.  
  13. int cmp(int x,int y)
  14. {
  15. return sum[x]<sum[y];
  16. }
  17.  
  18. int main()
  19. {
  20. scanf("%d%d",&n,&T);
  21. for (i=;i<=n;++i)
  22. scanf("%d",&a[i]);
  23.  
  24. for (i=;i<=n;++i) scanf("%d",&t[i]);
  25. for (i=;i<=n;++i)
  26. {
  27. if (t[i]==T) ans+=a[i];
  28. else if (t[i]<T) id[++id[]]=i,sum[i]=T-t[i];
  29. else ID[++ID[]]=i,sum[i]=t[i]-T;
  30. }
  31. sort(id+,id+id[]+,cmp);
  32. sort(ID+,ID+ID[]+,cmp);
  33. long long suma=,sumb=;
  34. for (i=;i<=id[];++i)
  35. suma+=1ll*sum[id[i]]*a[id[i]];
  36. for (i=;i<=ID[];++i)
  37. sumb+=1ll*sum[ID[i]]*a[ID[i]];
  38. if (suma<sumb)
  39. {
  40. swap(suma,sumb);
  41. for (i=;i<=n;++i) swap(ID[i],id[i]);
  42. }
  43. for (i=;i<=ID[];++i) ans+=a[ID[i]];
  44. for (i=;i<=id[];++i)
  45. if (1ll*sum[id[i]]*a[id[i]]>=sumb)
  46. {
  47. ans+=.*sumb/sum[id[i]];
  48. break;
  49. }
  50. else
  51. {
  52. ans+=a[id[i]];
  53. sumb-=1ll*sum[id[i]]*a[id[i]];
  54. }
  55. printf("%.10lf\n",ans);
  56. }

【代码】

  1. #include<bits/stdc++.h>
  2.  
  3. #define N 500005
  4.  
  5. using namespace std;
  6.  
  7. int i,j,m,n,p,k,a[N],ty,x;
  8.  
  9. long long b[N]; //表示前K个数的前缀和
  10.  
  11. double check(int x) //平均数
  12. {
  13. return .*(b[x-]+a[n])/x;
  14. }
  15.  
  16. int main()
  17. {
  18. scanf("%d",&m);
  19. for (;m--;)
  20. {
  21. scanf("%d",&ty); //操作名称
  22.  
  23. if (ty==) //插入数的操作
  24. {
  25. scanf("%d",&x);
  26. a[++n]=x;
  27. b[n]=b[n-]+x;
  28. }
  29.  
  30. else
  31. {
  32. int l=,r=n;
  33. while (r-l>) //保留一个尽量大的小三分区间,比如只有10个数
  34. {
  35. int len=(r-l+)/,mid1=l+len,mid2=mid1+len; //三分,每次缩小三分之一
  36. if (check(mid1)<check(mid2)) r=mid2; //因为函数图像是倒着的
  37. else l=mid1;
  38. }
  39.  
  40. //在区间内部枚举一下
  41. double ans=;
  42. for (i=l;i<=r;++i) ans=max(ans,a[n]-check(i));
  43. printf("%.10lf\n",ans);
  44. }
  45.  
  46. }
  47. }

五一培训 DAY1的更多相关文章

  1. 五一培训 清北学堂 DAY1

    今天是冯哲老师的讲授~ 1.枚举 枚举也称作穷举,指的是从问题所有可能的解的集合中一一枚举各元素. 用题目中给定的检验条件判定哪些是无用的,哪些是有用的.能使命题成立的即为其解. 例一一棵苹果树上有n ...

  2. 纪中2018暑假培训day1提高b组改题记录

    收到意见,认为每天的程序和随笔放在一起写的博客太长了,于是分开整理 day1 模拟赛,看了看提高a组t1的样例就不太想写,于是转而写b组 t1: Description 给定一个n个点m条边的有向图, ...

  3. 中山纪念中学培训DAY1

    哇啊啊啊啊啊啊$……$ 并不像说环境怎么样. $Day1$模拟赛 稳重一点选了提高$B$ 然后$5min$后: $t1$装压$DP$最短路 $t2$裸地贪心 $t3……$哇$t3$怎么做啊啊啊啊. $ ...

  4. 五一培训 清北学堂 DAY4

    今天上午是钟皓曦老师的讲授,下午是吴耀轩老师出的题给我们NOIP模拟考了一下下(悲催暴零) 今天的内容——数论 话说我们可能真的是交了冤枉钱了,和上次清明培训的时候的课件及内容一样(哭. 整除性 质数 ...

  5. 常州培训 day1 解题报告

    第一题:(骗分容易,AC难.) 题目大意: 给出一个字符串,找出满足条件A的区间的个数.A:字符A,B,C的出现次数相同. 都出现0次也算,区间的长度可以是0(就是只有一个数).30% |S| ≤ 1 ...

  6. 五一培训 清北学堂 DAY2

    今天还是冯哲老师的讲授~~ 今日内容:简单数据结构(没看出来简单qaq) 1.搜索二叉树 前置技能 一道入门题在初学OI的时候,总会遇到这么一道题.给出N次操作,每次加入一个数,或者询问当前所有数的最 ...

  7. 五一培训 清北学堂 DAY3

    今天是钟皓曦老师的讲授~ 今天的内容:动态规划 1.动态规划 动态规划很难总结出一套规律 例子:斐波那契数列  0,1,1,2,3,5,8,…… F[0]=0 F[1]=1 F[[n]=f[n-1]+ ...

  8. 泉五培训Day1

    T1 树学 题目 [问题描述] 给定一颗 n 个点的树,树边带权,试求一个排列 P,最大化下式 其中,calc(a, b)表示树上由a到b经过的最大边权. [输入格式] 第一行一个整数 n,表示点数下 ...

  9. 性能测试培训day1

    测试本质: 1构造测试数据和期望结果 2执行 3验证 自动化测试: 写完代码,单元测试测代码逻辑,单元测试搞清楚代码逻辑就行了(白盒测试)先静态,运行前用工具扫描BUG例如(a==11写成a=11), ...

随机推荐

  1. centos7下NFS使用与配置

    NFS是Network File System的缩写,即网络文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. nfs为什么需要RPC?因为NFS支持的功能很多,不同功能会 ...

  2. LeetCode 34 - 在排序数组中查找元素的第一个和最后一个位置 - [二分][lower_bound和upper_bound]

    给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...

  3. Java 通过getbean取出的类为什么要强转为接口类

    这个问题是之前一个同学问我的,这些是我在网上找到的资料,由于我自己也没有完全搞明白,先大概记录一下 首先问题是为什么在bean文件中注入的是实现类,但是通过getBean()取出的时候却必须强制转化为 ...

  4. 4. Scala程序流程控制

    4.1 程序流程控制说明 在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句,顺序控制,粉质控制,循环控制 温馨提示:Scala语言中控制结构和Java语言中的 ...

  5. springboot+rediscluster

    @EnableCaching @Configuration public class RedisConfiguration extends CachingConfigurerSupport { @Au ...

  6. 关于Android的fragment的使用

    fragment的静态使用 首先创建两个fragment,就把fragment当成activity去写布局,第一个是fragment_title: <LinearLayout xmlns:and ...

  7. Redis在windows下安装与配置

    一.安装Redis 1. Redis官网下载地址:http://redis.io/download,下载相应版本的Redis,在运行中输入cmd,然后把目录指向解压的Redis目录. 2.启动服务命令 ...

  8. uboot - the bootloader of linux

    [转载]https://blog.csdn.net/kernel_yx/article/details/53045424 最近一段时间一直在做uboot移植相关的工作,需要将uboot-2016-7移 ...

  9. MATLAB矩阵运算

    1. 矩阵的加减乘除和(共轭)转置 (1) 矩阵的加法和减法 如果矩阵A和B有相同的维度(行数和列数都相等),则可以定义它们的和A+B以及它们的差A-B,得到一个与A和B同维度的矩阵C,其中Cij=A ...

  10. python安装画图模块pillow

    步骤一: install pillow (注意导入是 import PIL )       步骤二:如果pycharm中import选择不到,则需要在settings中导入下             ...