• 28上午
      • 骚猪选讲
    • 28下午
      • BOZJ 1081 [SCOI2005]超级格雷码

感觉就是一个找规律,然后模拟输出。
半天没找到一个比较简便的模拟方法,
这份代码是学习网上一位大佬的,很巧妙。

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. using namespace std;
  5. int n,m,pow[40];
  6. void print(int y){
  7. if(y<10) printf("%d",y);
  8. else printf("%c",y-10+'A');
  9. }
  10. int main(){
  11. scanf("%d%d",&n,&m);
  12. pow[0]=1;
  13. for(int i=1;i<=n;i++) pow[i]=pow[i-1]*m;
  14. for(int i=0;i<pow[n];i++){
  15. for(int j=n-1;j>=0;j--){
  16. int x=i/pow[n-j];
  17. int y=(i/pow[n-j-1])%m;
  18. if(x&1) print(m-y-1);
  19. else print(y);
  20. }
  21. printf("\n");
  22. }
  23. return 0;
  24. }
      • BOZJ 1082 [SCOI2005]栅栏

二分+dfs_check(剪枝)。(感觉这个模型不容易看出来,太弱了555)
   
对木板和木材从小到大排序。
先二分答案mid,然后我们看看是否可以弄出前mid个小木板。
check时,用贪心策略:即尽量用小的木材去造大的木板。
所以从大到小枚举前mid个木板,然后从小到大枚举木材。
   
至于剪枝,就是记录浪费的木材,即某次裁剪后剩下的木材都不足以造最小的木板,就计入waste,
如果 waste+need(前mid个木板的总长)>tot(木材总长),就直接return 0;

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. int A[55],totA,B[1005],sumB[1005],waste,need;
  7. int n,m;
  8. bool dfs(int p1,int p2){
  9. if(p1==0) return 1;
  10. if(waste+need>totA) return 0;
  11. for(int i=p2;i<=m;i++){
  12. if(A[i]>=B[p1]){
  13. A[i]-=B[p1];
  14. if(A[i]<B[1]) waste+=A[i];
  15. bool fg=dfs(p1-1,B[p1]==B[p1-1]?p2:1);
  16. if(A[i]<B[1]) waste-=A[i];
  17. A[i]+=B[p1];
  18. if(fg) return 1;
  19. }
  20. }
  21. return 0;
  22. }
  23. int binary(int l,int r){
  24. int mid,ans=0;
  25. while(l<=r){
  26. mid=(l+r)>>1;
  27. need=sumB[mid];
  28. if(dfs(mid,1)) ans=mid,l=mid+1;
  29. else r=mid-1;
  30. }
  31. return ans;
  32. }
  33. int main(){
  34. scanf("%d",&m);
  35. for(int i=1;i<=m;i++) scanf("%d",&A[i]);
  36. scanf("%d",&n);
  37. for(int i=1;i<=n;i++) scanf("%d",&B[i]);
  38. sort(A+1,A+m+1); sort(B+1,B+n+1);
  39. for(int i=1;i<=m;i++) totA+=A[i];
  40. for(int i=1;i<=n;i++) sumB[i]=sumB[i-1]+B[i];
  41. int ans=binary(0,n);
  42. printf("%d",ans);
  43. return 0;
  44. }
      • BOZJ 1083 [SCOI2005]繁忙的都市 
        最小生成树kruskal。

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. struct edge{
  7. int u,v,w;
  8. bool operator <(const edge &rtm) const{
  9. return w<rtm.w;
  10. }
  11. }e[10005];
  12. int fa[305];
  13. int n,m,need;
  14. int find(int x){
  15. return x==fa[x]?x:fa[x]=find(fa[x]);
  16. }
  17. int main(){
  18. scanf("%d%d",&n,&m);
  19. for(int i=1;i<=n;i++) fa[i]=i;
  20. for(int i=1;i<=m;i++)
  21. scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
  22. sort(e+1,e+m+1); need=n-1;
  23. for(int i=1;i<=m;i++){
  24. int fu=find(e[i].u),fv=find(e[i].v);
  25. if(fu==fv) continue;
  26. fa[fv]=fu; need--;
  27. if(!need){
  28. printf("%d %d",n-1,e[i].w);
  29. break;
  30. }
  31. }
  32. return 0;
  33. }
    • 29下午+晚上
      • 看了看bzoj的10月月赛题(和题解),后两道没看懂、、、
      • BOZJ 5071 [Lydsy十月月赛]小A的数字

找到 A序列的变化规律,即每次操作使得A的前缀序列中的相邻两个元素交换位置。
代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define ll long long
  6. using namespace std;
  7. ll sumA[100005],sumB[100005];
  8. int main(){
  9. int T,n;
  10. scanf("%d",&T);
  11. while(T--){
  12. scanf("%d",&n);
  13. for(int i=1;i<=n;i++) scanf("%lld",&sumA[i]),sumA[i]+=sumA[i-1];
  14. for(int i=1;i<=n;i++) scanf("%lld",&sumB[i]),sumB[i]+=sumB[i-1];
  15. sort(sumA+1,sumA+n+1);
  16. sort(sumB+1,sumB+n+1);
  17. for(int i=1;i<=n+1;i++){
  18. if(i==n+1) printf("YES\n");
  19. if(sumA[i]!=sumB[i]){
  20. printf("NO\n");
  21. break;
  22. }
  23. }
  24. }
  25. return 0;
  26. }
      • BOZJ 5072 [Lydsy十月月赛]小A的树

很扯的树形dp。
看官方题解吧(感觉70%数据的题解有毒,怎么搞出的n^3?)
然后这份代码学习网上的一位大佬的。
在dp转移时,要多开两个数组防止用到本次转移的dp结果,
(当然也可以逆向枚举,但是因为for循环大了一点,会超时、、、)

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. using namespace std;
  5. struct edge{
  6. int to,next;
  7. }e[5005*2];
  8. int head[5005],color[5005];
  9. int dmin[5005][5005],dmax[5005][5005],amin[5005],amax[5005],siz[5005],dn[5005],dx[5005];
  10. int n,q,ent;
  11. void read(int &x){
  12. static int f; static char ch;
  13. x=0; f=1; ch=getchar();
  14. while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  15. while('0'<=ch&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
  16. x=x*f;
  17. }
  18. void add(int u,int v){
  19. e[ent]=(edge){v,head[u]};
  20. head[u]=ent++;
  21. }
  22. void dp(int u,int fa){
  23. if(color[u]) dmax[u][1]=dmin[u][1]=1;
  24. else dmax[u][1]=dmin[u][1]=0;
  25. siz[u]=1;
  26. for(int i=head[u];i;i=e[i].next){
  27. int v=e[i].to;
  28. if(v==fa) continue;
  29. dp(v,u);
  30. memcpy(dx,dmax[u],sizeof(dmax[u])),memcpy(dn,dmin[u],sizeof(dmin[u]));
  31. for(int j=1;j<=siz[u];j++)
  32. for(int k=1;k<=siz[v];k++){
  33. dx[j+k]=max(dx[j+k],dmax[u][j]+dmax[v][k]);
  34. dn[j+k]=min(dn[j+k],dmin[u][j]+dmin[v][k]);
  35. }
  36. siz[u]+=siz[v];
  37. for(int j=1;j<=siz[u];j++)
  38. dmax[u][j]=dx[j],dmin[u][j]=dn[j];
  39.  
  40. }
  41. for(int i=1;i<=siz[u];i++){
  42. amax[i]=max(amax[i],dmax[u][i]);
  43. amin[i]=min(amin[i],dmin[u][i]);
  44. }
  45. }
  46. int main(){
  47. int T; read(T);
  48. while(T--){
  49. memset(dmin,0x3f,sizeof(dmin));
  50. memset(amin,0x3f,sizeof(amin));
  51. memset(dmax,0,sizeof(dmax));
  52. memset(amax,0,sizeof(amax));
  53. memset(head,0,sizeof(head));
  54. ent=2;
  55. read(n); read(q);
  56. for(int i=1,u,v;i<n;i++){
  57. read(u); read(v);
  58. add(u,v); add(v,u);
  59. }
  60. for(int i=1;i<=n;i++) read(color[i]);
  61. dp(1,0);
  62. for(int i=1,x,y;i<=q;i++){
  63. scanf("%d%d",&x,&y);
  64. if(amin[x]<=y&&y<=amax[x]) puts("YES");
  65. else puts("NO");
  66. }
  67. printf("\n");
  68. }
  69. return 0;
  70. }
      • BOZJ 5073 [Lydsy十月月赛]小A的咒语

dp[i][j] 表示到了A串的第i位,已经选了j段,构成B串的最大长度。
转移,刷表法:
1).A串的下一位不贡献,即不是构成B串的一份子。
   dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
2).A串的i位以后要贡献,即尝试去成为B串的一份子。
   显然,按照贪心策略,此时选的要尽量长,
   令l=lcp(A[i+1],B[dp[i][j]+1]),即A串后缀A[i+1~n-1]与B串后缀B[dp[i][j]+1~m-1]的最长公共前缀。
   dp[i+l][j+1]=max(dp[i+l][j+1],dp[i][j]+l)
   然后就是后缀数组+RMQ表维护lcp
   
网上还有一种不用后缀数组直接dp的方法,(但我没看懂)。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #define MAXN 100005
  5. using namespace std;
  6. char s[MAXN*2];
  7. int sa[MAXN*2],rk[MAXN*2],ht[MAXN*2];
  8. int dp[MAXN][105],st[MAXN*2][20],log2[MAXN*2];
  9. void print(int n){
  10. puts("sa:");
  11. for(int i=0;i<n;i++) printf("%d ",sa[i]); puts("");
  12. puts("rk:");
  13. for(int i=0;i<n;i++) printf("%d ",rk[i]); puts("");
  14. puts("ht:");
  15. for(int i=0;i<n;i++) printf("%d ",ht[i]); puts("");
  16. }
  17. bool cmp(int *y,int len,int k,int p1,int p2){
  18. int a=y[p1],b=y[p2];
  19. int aa=p1+k<len?y[p1+k]:-1,bb=p2+k<len?y[p2+k]:-1;
  20. return a==b&&aa==bb;
  21. }
  22. void build(int n,int m){
  23. static int wa[MAXN*2],wb[MAXN*2],c[MAXN*2],*x,*y,p;
  24. x=wa; y=wb;
  25. for(int i=0;i<m;i++) c[i]=0;
  26. for(int i=0;i<n;i++) c[x[i]=s[i]]++;
  27. for(int i=1;i<m;i++) c[i]+=c[i-1];
  28. for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
  29. for(int k=1;k<n;k<<=1){
  30. p=0;
  31. for(int i=n-k;i<n;i++) y[p++]=i;
  32. for(int i=0;i<n;i++) if(sa[i]-k>=0) y[p++]=sa[i]-k;
  33.  
  34. for(int i=0;i<m;i++) c[i]=0;
  35. for(int i=0;i<n;i++) c[x[y[i]]]++;
  36. for(int i=1;i<m;i++) c[i]+=c[i-1];
  37. for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
  38.  
  39. m=1; swap(x,y); x[sa[0]]=0;
  40. for(int i=1;i<n;i++)
  41. x[sa[i]]=cmp(y,n,k,sa[i-1],sa[i])?m-1:m++;
  42. if(m>=n) break;
  43. }
  44. for(int i=0;i<n;i++) rk[sa[i]]=i;
  45. int h=0;
  46. for(int i=0,j;i<n;i++){
  47. if(h) h--;
  48. if(rk[i]!=0){
  49. j=sa[rk[i]-1];
  50. while(i+h<n&&j+h<n&&s[i+h]==s[j+h]) h++;
  51. }
  52. ht[rk[i]]=h;
  53. }
  54. for(int i=1;i<n;i++) st[i][0]=ht[i];
  55. for(int k=1;(1<<k)<n;k++)
  56. for(int i=1<<k;i<n;i++)
  57. st[i][k]=min(st[i-(1<<(k-1))][k-1],st[i][k-1]);
  58. }
  59. int lcp(int i,int j){
  60. i=rk[i]; j=rk[j];
  61. if(i>j) swap(i,j); i++;
  62. int k=log2[j-i+1];
  63. return min(st[i+(1<<k)-1][k],st[j][k]);
  64. }
  65. int main(){
  66. log2[1]=0;
  67. for(int i=2;i<200000;i++) log2[i]=log2[i>>1]+1;
  68. int T; scanf("%d",&T);
  69. while(T--){
  70. int n,m,x; bool fg;
  71. memset(dp,0,sizeof(dp));
  72. scanf("%d%d%d",&n,&m,&x);
  73. scanf("%s",s); s[n]='%';
  74. scanf("%s",s+n+1); fg=0;
  75. build(n+m+1,301);
  76. for(int i=-1;i<n;i++)
  77. for(int j=0;j<=min(i+1,x);j++){
  78. int d=i>=0?dp[i][j]:0;
  79. if(d==m) fg=1;
  80. dp[i+1][j]=max(dp[i+1][j],d);
  81. int l=(i+1<n&&n+1+d<n+m+1)?lcp(i+1,n+1+d):0;
  82. if(l==0) continue;
  83. dp[i+l][j+1]=max(dp[i+l][j+1],d+l);
  84. }
  85. if(fg) printf("YES\n");
  86. else printf("NO\n");
  87. }
  88. return 0;
  89. }
      • BOZJ 5074 [Lydsy十月月赛]小B的数字

假设B序列为 b1,b2,b3.......
那同时也可以表示为 2^k1,2^k2,3^k3......
所以 x=2^(k1+k2+k3+......),令ak==k1+k2+k3+......
要使得每一个bi^ai(==2^(ki*ai))都能被x整除,
即需要满足(ki*ai)>=ak
所以 列出不等式:
     k1*a1>=ak
     k2*a2>=ak
     k3*a3>=ak
     .........
把左边的a移动到右侧
     k1>=ak/a1
     k2>=ak/a2
     k3>=ak/a3
     .........
再把所有式子相加得:
     ak>=ak/a1+ak/a2+ak/a3+......
即 1>=1/a1+1/a2+1/a3+......
所以只要判断这个不等式是否满足就好了。

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. using namespace std;
  5. const double eps=1e-8;
  6. int main(){
  7. int T; scanf("%d",&T);
  8. while(T--){
  9. double sum=0; int n;
  10. scanf("%d",&n);
  11. for(int i=1,a;i<=n;i++)
  12. scanf("%d",&a),sum+=1.0/a;
  13. if(sum<=1+eps) printf("YES\n");
  14. else printf("NO\n");
  15. }
  16. return 0;
  17. }

17.10.28&29的更多相关文章

  1. 小白的python之路Linux部分10/28&29

    属主属组其他人对文件的rwx权限 1.userdel删东西不全,会有残留,

  2. 10.28&29(NOIP模拟&修正&总结)

    三道题: T1:约数的约数的个数和.数论.但是简单暴力A了. T2:前k大的(带权点ai与带权点bi的和)的和.二分.骗40. T3:三维空间内每次减少有与空点的点,前后左右相连,求最短时间减为空.d ...

  3. NOIP模拟 17.9.28

    公交车[问题描述]市内有

  4. 使用yum快速升级CentOS 6.5内核到 3.10.28

    网上有不少升级CentOS内核的文章,如<CentOS 6.5 升级内核到 3.10.28>,大部分都是下载源码编译,有点麻烦. 在yum的ELRepo源中,有mainline(3.13. ...

  5. 20145236《网络对抗》进阶实验——64位Ubuntu 17.10.1 ROP攻击

    20145236<网络对抗>进阶实验--64位Ubuntu 17.10.1 ROP攻击 基础知识 ROP攻击 ROP全称为Retrun-oriented Programmming(面向返回 ...

  6. 第16次Scrum会议(10/28)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/28 17:20~17:32,总计12min.地点:东北师范 ...

  7. 背水一战 Windows 10 (28) - 控件(文本类): TextBox, PasswordBox

    [源码下载] 背水一战 Windows 10 (28) - 控件(文本类): TextBox, PasswordBox 作者:webabcd 介绍背水一战 Windows 10 之 控件(文本类) T ...

  8. [CareerCup] 17.10 Encode XML 编码XML

    17.10 Since XML is very verbose, you are given a way of encoding it where each tag gets mapped to a ...

  9. CentOS6.5升级内核到3.10.28 --已验证

    本文适用于CentOS 6.4, CentOS 6.5,估计也适用于其他Linux发行版. 1. 准备工作 确认内核及版本信息 [root@hostname ~]# uname -r 2.6.32-2 ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本) Day 2

    小队@JMUZJB-集美震惊部 一.Daily Scrum Meeting照片 二.Burndown Chart 燃尽图 三.项目进展 成员 工作 丘雨晨 环境配置 刘向东 数据库搭建,环境配置 江泽 ...

  2. verilog学习笔记(4)_有限状态机

    有限状态机: 有限状态机是由寄存器组和组合逻辑构成的硬件时序电路: - 其状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态: - 究竟转 ...

  3. 直方图均衡化及matlab实现

    在处理图像时,偶尔会碰到图像的灰度级别集中在某个小范围内的问题,这时候图像很难看清楚.比如下图: 它的灰度级别,我们利用一个直方图可以看出来(横坐标从0到255,表示灰度级别,纵坐标表示每个灰度级别的 ...

  4. 16-TypeScript装饰器模式

    在客户端脚本中,有一个类通常有一个方法需要执行一些操作,当我们需要扩展新功能,增加一些操作代码时,通常需要修改类中方法的代码,这种方式违背了开闭的原则. 装饰器模式可以动态的给类增加一些额外的职责.基 ...

  5. 职场选择之大公司 VS 小公司

    其实这是个非常难回答的问题,很多职场新人都会有类似的顾虑和疑问. 这个问题就好比业界比较容易引起争议的编程语言哪个是最好的一样.大公司还是小公司里面发展,只有身处其中才能体会,如人饮水,冷暖自知. 笔 ...

  6. JAVA_SE基础——17.方法的重载

    方法重载: 方法重载就是方法名称重复,加载参数不同. 具体规范: 一.方法名一定要相同. 二.方法的参数表必须不同,包括参数的类型或个数,以此区分不同的方法体. 1.如果参数个数不同,就不管它的参数类 ...

  7. js进度条小事例

    <style> #div1{width: 500px;height: 20px;border: 1px solid gray;} #div2{height: 20px;width: 0px ...

  8. SecureCRT 7.3注册机激活

    SecureCRT是一款很好用的远程登陆管理工具 工具和注册机下载链接:http://pan.baidu.com/s/1jImWiMU 密码:0yox 以管理管运行keygen.exe(一定要以管理员 ...

  9. Javascript 装饰器极速指南

    pablo.png Decorators 是ES7中添加的JavaScript新特性.熟悉Typescript的同学应该更早的接触到这个特性,TypeScript早些时候已经支持Decorators的 ...

  10. Spark入门(1-3)Spark的重要概念

    1.什么是弹性分布式数据集? Spark提出了RDD(Resilient Distributed Datasets)这么一个全新的概念,RDD弹性分布式数据集是并行.容错的分布式数据结构:可以将RDD ...