当前位置:   article > 正文

8.29淘汰赛_淘汰赛 r语言

淘汰赛 r语言

 先总结一下吧,打的平平,满分五分的话可以打三分。

做了并查集、fylod、stl、处理字符串。

可惜没做出来的   造字(明显dp不熟,不敢往那方面想;递归不行,光顾着找规律)

                            线段树找右面最小值(不静下来好好分析,多取点画图)。

其他的来不及多看题多思考。

需要多练习,多打比赛,调整心态~

  • 线段树:找指定位置的 右边 离它最近的 比某个值大的数 的位置

精卫当前所在位置为K(1<=K<=N),精卫会寻找位置在她的西边(不包括她所在的位置K)并且离她距离最近的,石头数大于S(1<=S<=1e9)的石堆

pos在mid的左边的时候,那么我们就知道了在L到mid的区间上有大于S的值,但是我们不知道pos的右边是否有大于S的值,所以我们需要先进入左子树,如果找到了这个值说明pos的右边有大于S的值;否则pos右边没有,这时我们还得去mid的右边寻找另一个大于S的值。需要注意判断这个值是否存在时,引入变量ans,用来判断是否存在,最后再写return ans;

pos在mid的右边的时候我们只能在pos的后面找到位置, 所以必须查询右子树。

  1. #include<cstdio>
  2. #include<string>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. typedef long long ll;
  8. const ll maxn=1e9+5;
  9. const ll maxm=250010;
  10. ll x,y,ans;
  11. ll n,m,q;
  12. struct node
  13. {
  14. ll l,r,w;
  15. }t[maxm*4+5];
  16. void build(ll l,ll r,ll k)
  17. {
  18. t[k].l=l;
  19. t[k].r=r;
  20. if(l==r)
  21. {
  22. scanf("%lld",&t[k].w);return ;
  23. }
  24. ll mid=(l+r)>>1;
  25. build(l,mid,k*2);
  26. build(mid+1,r,k*2+1);
  27. t[k].w=max(t[k*2].w,t[k*2+1].w);
  28. }
  29. void add(ll k)
  30. {
  31. if(t[k].l==t[k].r)
  32. {
  33. t[k].w=0;return ;
  34. }
  35. ll mid=(t[k].l+t[k].r)/2;
  36. if(x<=mid) add(k*2);
  37. else add(k*2+1);
  38. t[k].w=max(t[k*2].w,t[k*2+1].w);
  39. }
  40. void addd(ll k)
  41. {
  42. if(t[k].l==t[k].r)
  43. {
  44. t[k].w=y;return ;
  45. }
  46. ll mid=(t[k].l+t[k].r)/2;
  47. if(x<=mid) addd(k*2);
  48. else addd(k*2+1);
  49. t[k].w=max(t[k*2].w,t[k*2+1].w);
  50. }
  51. ll ask(ll k)
  52. {
  53. if(t[k].l==t[k].r)
  54. {
  55. if(t[k].w>y) return t[k].l;
  56. else return -1;
  57. }
  58. ll mid=(t[k].l+t[k].r)/2;
  59. ll ans=0;
  60. if(mid>x&&t[2*k].w>y)
  61. {
  62. ans=ask(2*k);
  63. if(ans==-1) ans=ask(2*k+1);
  64. }
  65. else ans=ask(2*k+1);
  66. return ans;
  67. }
  68. int main()
  69. {
  70. scanf("%lld%lld",&n,&m);
  71. build(1,n,1);
  72. while(m--)
  73. {
  74. scanf("%lld%lld%lld",&q,&x,&y);
  75. if(q==1)
  76. {
  77. if(x==n||t[1].w<=y)
  78. {
  79. printf("-1\n");
  80. }
  81. else
  82. {
  83. ll ans=ask(1);
  84. printf("%lld\n",ans);
  85. if(ans!=-1)
  86. {
  87. x=ans;add(1);
  88. }
  89. }
  90. }
  91. else if(q==2)
  92. {
  93. addd(1);
  94. }
  95. }
  96. return 0;
  97. }
  • 仓颉造字

              即第N个字可以如图所示分成4个部分,前3个部分,每个小部分都是字N-1,最后一个部分都是空格(ASCII码为32)

  1. #include<cstdio>
  2. #include<string>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<cmath>
  7. using namespace std;
  8. typedef long long ll;
  9. const int maxn=1030;
  10. char dp[12][maxn][maxn];
  11. int main()
  12. {
  13. int n,cha,mx;
  14. scanf("%d",&n);
  15. dp[0][0][0]='*';
  16. for(int k=1;k<=n;k++)
  17. {
  18. cha=(int)pow(2,k-1);
  19. mx=(int)pow(2,k);
  20. for(int i=0;i<mx;i++)
  21. {
  22. for(int j=0;j<mx;j++)
  23. {
  24. if(i>=cha&&j>=cha) dp[k][i][j]=' ';
  25. else dp[k][i][j]=dp[k-1][i%cha][j%cha];
  26. }
  27. }
  28. }
  29. mx=(int)pow(2,n);
  30. for(int i=0;i<mx;i++)
  31. {
  32. for(int j=0;j<mx-i;j++)
  33. {
  34. printf("%c",dp[n][i][j]);
  35. }
  36. if(i!=mx-1) printf("\n");
  37. }
  38. return 0;
  39. }

 dp不敢想三维;看了同学的代码,觉得自己想的太多了,完全可以按照题意去一块一块填写。这么简单的题没错出来,太浮躁太浮躁

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. const ll mod=500500507;
  5. const int maxn=500000+10;
  6. int n,m;
  7. int main()
  8. {
  9. scanf("%d",&n);
  10. char s1[1100][1100];
  11. if(!n)
  12. {
  13. printf("*");
  14. return 0;
  15. }
  16. s1[1][1]='*';
  17. int len=1;
  18. for(int k=1;k<=n;k++)
  19. {
  20. len=k==1?len:len*2;
  21. for(int i=len+1;i<=len*2;i++)
  22. for(int j=len+1;j<=len*2;j++)
  23. s1[i][j]=' ';
  24. for(int i=1;i<=len;i++)
  25. for(int j=len+1;j<=len*2;j++)
  26. s1[i][j]=s1[i][j-len];
  27. for(int i=len+1;i<=len*2;i++)
  28. for(int j=1;j<=len;j++)
  29. s1[i][j]=s1[i-len][j];
  30. }
  31. for(int i=1;i<=len*2;i++)
  32. {
  33. for(int j=1;j<=len*2;j++)
  34. printf("%c",s1[i][j]);
  35. if(i!=len*2) printf("\n");
  36. }
  37. return 0;
  38. }
  • KMP应用,next[len]表示字符串最长前缀后缀相同的长度。

1.对于一个字符串S,定义以下n个字符串,S[i]表示一个这样的字符串:截取S的前i个字符,让截取部分的第一个字符接在剩下部分的最后一个字符后面。例:对于字符串S =“abcdef”,S[2]表示字符串“cdefab”。

2.将n个字符串进行分组,相同字符串为一组。

3.定义序列L,表示为每一组的字符串的编号按从小到大排列的序列。

4.按照L的字典序从小到大输出所有分组。

例:S =“abab”,S[0] =“abab”,S[1] =“baba”,S[2] =“abab”,S[3] =“baba”。分组L[]为(0, 2),(1, 3)。对L数组排序后:L[1]=(0, 2),L[2]=(1, 3)。因为0比1小。

  1. abab
  2. 2
  3. 2 0 2
  4. 2 1 3
  1. #include<cstdio>
  2. #include<string>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. typedef long long ll;
  8. const int maxn=1000005;
  9. string s;
  10. int ne[maxn];
  11. int len,zu;
  12. void getnext()
  13. {
  14. int i=0,j=-1;
  15. ne[0]=-1;
  16. while(i<len)
  17. {
  18. if(j==-1||s[i]==s[j])
  19. {
  20. i++;j++;ne[i]=j;
  21. }
  22. else j=ne[j];
  23. }
  24. }
  25. int main()
  26. {
  27. cin>>s;
  28. len=s.length();
  29. getnext();
  30. int jie=len-ne[len];//找到循环节!!
  31. int zu;
  32. if(len%jie!=0)
  33. zu=len;
  34. else
  35. zu=jie;
  36. printf("%d\n",zu);
  37. int x=len/zu;
  38. int y;
  39. for(int i=1;i<=zu;i++)
  40. {
  41. printf("%d ",x);
  42. y=i-1;
  43. for(int j=1;j<=x;j++)
  44. {
  45. printf("%d ",y);y+=zu;
  46. }
  47. printf("\n");
  48. }
  49. return 0;
  50. }
  • 求因子个数是2的n次 的最小数

对于一个自然数N,都可以分解质因子得到如下形式:p1、p2、p3……pk都是质数。

 筛法求质数
这种方法高效,但内存消耗较大。

思想:去除要求范围内所有的合数,剩下的就是素数了,而任何合数都可以表示为素数的乘积,因此如果已知一个数为素数,则它的倍数  都为合数。
实现:把从1开始的、某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉。

           剩下的数中选择最小的数是素数,然后去掉它的倍数。

           依次类推,直到筛子为空时结束。

  1. #include<cstdio>
  2. #include<string>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. using namespace std;
  8. typedef long long ll;
  9. const ll mod=500500507;
  10. const ll maxn=1e7+5;
  11. bool prime[maxn];
  12. ll n,ans=1,tp;
  13. priority_queue<ll,vector<ll>,greater<ll> >q;
  14. void judge()
  15. {
  16. ll cnt=0;
  17. memset(prime,0,sizeof(prime));
  18. for(ll i=2;i<maxn;i++)
  19. {
  20. if(cnt==n) return ;
  21. if(!prime[i])
  22. {
  23. q.push(i);cnt++;
  24. }
  25. for(ll j=i*2;j<maxn;j+=i)
  26. {
  27. prime[j]=1;
  28. }
  29. }
  30. }
  31. int main()
  32. {
  33. cin>>n;
  34. judge();
  35. while(n--)
  36. {
  37. tp=q.top();
  38. q.pop();
  39. q.push(tp*tp);
  40. ans=(ans*tp)%mod;
  41. }
  42. cout<<ans<<endl;
  43. return 0;
  44. }
  • 夸父逐日

两个位置同时变化,要记录是否处于过某个状态,需要用结构体存起来,v开二维数组。

  1. #include<cstdio>
  2. #include<string>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<vector>
  8. using namespace std;
  9. const int maxn=1005;
  10. int n,m,l,x,y,a,b;
  11. bool v[maxn][maxn];
  12. vector <int> jnn[maxn];
  13. struct sta
  14. {
  15. int x,y,d;
  16. };
  17. int main()
  18. {
  19. scanf("%d%d%d%d%d",&n,&m,&l,&x,&y);
  20. memset(v,false,sizeof(v));
  21. for(int i=1;i<=m;i++)
  22. {
  23. scanf("%d%d",&a,&b);
  24. jnn[a].push_back(b);
  25. jnn[b].push_back(a);
  26. }
  27. queue<sta> q;
  28. sta tp;
  29. tp.x=x;tp.y=y;tp.d=0;
  30. q.push(tp);
  31. v[x][y]=true;
  32. while(!q.empty())
  33. {
  34. tp=q.front();
  35. if(tp.x==tp.y) break;
  36. q.pop();
  37. if(tp.d>l) continue;
  38. sta sc;
  39. sc.x=(tp.x+1)%(n+1);
  40. sc.y=(tp.y+2)%(n+1);
  41. sc.d=tp.d+1;
  42. if(!v[sc.x][sc.y])
  43. {
  44. q.push(sc);
  45. v[sc.x][sc.y]=true;
  46. }
  47. int len=jnn[tp.x].size();
  48. for(int i=0;i<len;i++)
  49. {
  50. sc.x=jnn[tp.x][i];
  51. if(!v[sc.x][sc.y])
  52. {
  53. q.push(sc);
  54. v[sc.x][sc.y]=true;
  55. }
  56. }
  57. }
  58. if(!q.empty()) printf("%d\n",tp.d);
  59. else printf("-1\n");
  60. return 0;
  61. }
  • 分割字符串,最大长度为5,求分割相加后的最大值

  1. #include<cstdio>
  2. #include<string>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<iostream>
  6. using namespace std;
  7. typedef long long ll;
  8. const ll maxn=1010;
  9. const ll INF=0;
  10. ll dp[maxn][maxn];
  11. ll val[maxn][7];
  12. char s[maxn];
  13. ll n,len,num;
  14. void get()
  15. {
  16. for(ll i=1;i<=len;i++)
  17. {
  18. num=0;
  19. for(ll j=1;j<=5;j++)
  20. {
  21. if(i+j>len+1) continue;
  22. num*=10;
  23. num+=(s[i+j-1]-'0');
  24. val[i][j]=num;
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. scanf("%s",s+1);
  31. len=strlen(s+1);
  32. scanf("%lld",&n);
  33. if(n>len||len>5*n)
  34. printf("-1\n");
  35. else
  36. {
  37. for(ll i=0;i<=len;i++)
  38. {
  39. for(ll j=0;j<=n;j++)
  40. {
  41. dp[i][j]=INF;
  42. }
  43. }
  44. get();
  45. dp[0][0]=0;
  46. for(ll i=1;i<=len;i++)
  47. {
  48. for(ll j=1;j<=n;j++)
  49. {
  50. if(j>i) break;
  51. for(ll k=1;k<=5;k++)
  52. {
  53. if(i-k+1<=0) break;
  54. if(j>i-k+1) break;
  55. dp[i][j]=max(dp[i][j],dp[i-k][j-1]+val[i-k+1][k]);
  56. }
  57. }
  58. }
  59. printf("%lld\n",dp[len][n]);
  60. }
  61. return 0;
  62. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/783034
推荐阅读
相关标签
  

闽ICP备14008679号