当前位置:   article > 正文

新生周赛小结

新生周赛


搜索加大数的周赛,结果不是很让人满意啊~我这队长水平一般,只能提供环境希望他们多努力努力了~

把几道不算水的题拿出来解析一下~

A  Zipper

一道算搜索的递归题,题目大意是,给三个字符串,问第三个是否是前两个字符串嵌套成的.题目叫拉链~基本就那意思了.

基本思想就是递归对比,有几个要注意的地方:

1. 要从后往前比,

2. 当a[i]==b[j]时要挨个试.

源代码:

  1. #include <myhead>
  2. const int N=500;
  3. char a[N],b[N],c[N];
  4. int dfs(int x,int y,int z) {
  5. if(z<0) {
  6. return true;
  7. }
  8. if(x>=0&&a[x]==c[z]) {
  9. if(dfs(x-1,y,z-1))
  10. return true;
  11. }
  12. if(y>=0&&b[y]==c[z]) {
  13. if(dfs(x,y-1,z-1))
  14. return true;
  15. }
  16. return false;
  17. }
  18. int main() {
  19. int t,m=1;
  20. scanf("%d",&t);
  21. while(t--) {
  22. scanf("%s%s%s",a,b,c);
  23. if(dfs(strlen(a)-1,strlen(b)-1,strlen(c)-1)) {
  24. printf("Data set %d: yes\n",m);
  25. } else {
  26. printf("Data set %d: no\n",m);
  27. }
  28. m=m+1;
  29. }
  30. return 0;
  31. }

还有一种做法是动态规划:

状态数组为 bool dp[i][j] , 也就是c[i+j]由a的前i个和b的前j个组成.

状态转移方程为:

dp[0][0] = 1;

dp[i][0]=dp[i-1][0]&&a[i-1]==c[i-1];       i>0

dp[0][j]=dp[0][j-1]&&b[j-1]==c[j-1];       j>0

dp[i][j] = (dp[i-1][j]&&a[i]==c[i+j]) || (dp[i][j-1]&&b[j]==c[i+j]);    i,j>0

源代码:

  1. #include <myhead.h>
  2. const int N=210;
  3. int main()
  4. {
  5. int t,m=1;
  6. bool dp[N][N];
  7. string a,b,c;
  8. cin>>t;
  9. while(t--) {
  10. memset(dp,0,sizeof(dp));
  11. cin>>a>>b>>c;
  12. dp[0][0]=1;
  13. for(size_t i=1;i<=a.size();++i) {
  14. dp[i][0]=(dp[i-1][0]&&a[i-1]==c[i-1]);
  15. }
  16. for(size_t j=1;j<=b.size();++j) {
  17. dp[0][j]=(dp[0][j-1]&&b[j-1]==c[j-1]);
  18. }
  19. for(size_t i=1;i<=a.size();++i) {
  20. for(size_t j=1;j<=b.size();++j) {
  21. dp[i][j]=(dp[i-1][j]&&a[i-1]==c[i+j-1]) || (dp[i][j-1]&&b[j-1]==c[i+j-1]);
  22. }
  23. }
  24. if(dp[a.size()][b.size()]) {
  25. printf("Data set %d: yes\n",m);
  26. } else {
  27. printf("Data set %d: no\n",m);
  28. }
  29. m=m+1;
  30. }
  31. return 0;
  32. }


B  Flip Game

http://blog.csdn.net/gj_fb_dabai/article/details/8742470

直接发链接了~


E  Square

http://poj.grids.cn/practice/1011/ 差不多~

题目大意:

给n个数 ,问这n个数能不能组成一个正方形.

解题思想:

一道普通的回溯法dfs, 状态组为(剩余长度num,已经分了几堆m,总共的剩余长度ssum,当前搜到的位置s);初始状态为 (sum/4,1,sum,0).

直接搜索当然会超时,需要有几点注意.

 1.当m==3时即可退出,因为若所有数的合sum%4==0 最后剩余的一组一定满足条件.

 2.对数组按从大到小顺序排序,这样只要搜索比当前值大的值即可.

状态转移方程为:

  1. num<0 -> return false;
  2. num==0
  3. -> m==3 -> return true;
  4. -> ssum%(4-m)==0 -> return (sum/4,m+1,ssum,0);
  5. else -> return flase;
  6. num!=0 -> (num-a[i],m,ssum-a[i],i+1);

源代码:

  1. #include <myhead.h>
  2. const int N=30;
  3. int n,sum;
  4. bool _hash[N];
  5. int dis[N];
  6. void init() {
  7. sum=0;
  8. memset(_hash,0,sizeof(_hash));
  9. scanf("%d",&n);
  10. for(int i=0;i<n;++i) {
  11. scanf("%d",&dis[i]);
  12. sum+=dis[i];
  13. }
  14. dis[n]=sum;
  15. sort(dis,dis+n);
  16. }
  17. bool dfs(int num,int m,int ssum,int s) {
  18. if(num==0) {
  19. if(m==3) {
  20. return true;
  21. } else {
  22. return dfs(sum/4,m+1,ssum,0);
  23. }
  24. }
  25. for(int i=s;i<n;++i) {
  26. if(!_hash[i]) {
  27. _hash[i]=true;
  28. if(dfs(num-dis[i],m,ssum-dis[i],i+1)) {
  29. return true;
  30. }
  31. _hash[i]=false;
  32. }
  33. }
  34. return false;
  35. }
  36. int main()
  37. {
  38. int t;
  39. scanf("%d",&t);
  40. while(t--) {
  41. init();
  42. if(sum%4==0&&dfs(sum/4,1,sum,0)) {
  43. puts("yes");
  44. } else {
  45. puts("no");
  46. }
  47. }
  48. return 0;
  49. }

G:集合加法

知道题本不是值得写的题,但是大一的童鞋们竟然全用双for循环写的,就现写了一个基数排序,然他们脑袋灵活点~

直接源代码了:

  1. #include <myhead.h>
  2. const int N=10010;
  3. int main()
  4. {
  5.     int t;
  6.     scanf("%d",&t);
  7.     while(t--) {
  8.         int s;
  9.         scanf("%d",&s);
  10.         int a_size,b_size,t;
  11.         int a[N],b[N];
  12.         memset(a,0,sizeof(a));
  13.         memset(b,0,sizeof(b));
  14.         scanf("%d",&a_size);
  15.         for(int i=0;i<a_size;++i) {
  16.             scanf("%d",&t);
  17.             a[t]++;
  18.         }
  19.         scanf("%d",&b_size);
  20.         for(int i=0;i<b_size;++i) {
  21.             scanf("%d",&t);
  22.             b[t]++;
  23.         }
  24.         int sum=0;
  25.         for(int i=1;i<s;++i) {
  26.             sum=sum+(a[i]*b[s-i]);
  27.         }
  28.         printf("%d\n",sum);
  29.     }
  30.     return 0;
  31. }

J:HTML

一道模拟题,也没什么意思,全场一看那么长都没写,我就写了~

根据要求 ,<br>换行, <hr>换行输出80个'-', 每80个字符换行一次. 

源代码:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main()
  5. {
  6. string szWord;
  7. int nCount = 0;
  8. int i;
  9. while (cin >> szWord)
  10. {
  11. if (szWord == "<hr>")
  12. {
  13. if (nCount != 0)
  14. cout << endl;
  15. for (i=0; i<80; i++)
  16. cout << "-";
  17. cout << endl;
  18. nCount = 0;
  19. }
  20. else if (szWord == "<br>")
  21. {
  22. cout << endl;
  23. nCount = 0;
  24. }
  25. else
  26. {
  27. if (nCount + szWord.size() + (nCount == 0 ? 0 : 1) > 80)
  28. {
  29. cout << endl;
  30. cout << szWord;
  31. nCount = szWord.size();
  32. }
  33. else
  34. {
  35. if (nCount != 0)
  36. cout << " ";
  37. cout << szWord;
  38. nCount += szWord.size() + 1;
  39. }
  40. }
  41. }
  42. cout << endl;
  43. return 0;
  44. }




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

闽ICP备14008679号