华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
12
返回列表 发新帖
楼主: admin
打印 上一主题 下一主题

刘伟杰李香来程序大楼

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
11#
 楼主| 发表于 2018-10-18 11:53:04 | 只看该作者
刘伟杰 发表于 2018-10-17 19:17
其实应该用搜索的,我错了

这个很有用,也需要掌握!
回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
12#
发表于 2018-10-19 19:10:03 | 只看该作者
luogu P1036 选数

一个质数判断加一个裸dfs即可

AC代码:
  1. #include <bits/stdc++.h>

  2. using namespace std;
  3. int n;
  4. int s[10000];
  5. int k;
  6. int ans;

  7. bool judge(int x)
  8. {
  9.     if(x == 1 || x == 0) return false;
  10.     if(x == 2) return true;

  11.     for(int i = 2;i <= x/2;i++)
  12.     {
  13.         if(x % i == 0) return false;
  14.     }
  15.     return true;
  16. }

  17. void dfs(int step,int cnt,int sum)
  18. {
  19.     if(step == n+1 || cnt == k)
  20.     {
  21.         if(cnt == k && judge(sum)) ans++;
  22.         return;
  23.     }
  24.     dfs(step+1,cnt+1,sum+s[step]);
  25.     dfs(step+1,cnt,sum);
  26.     return;
  27. }


  28. int main()
  29. {
  30.     scanf("%d%d",&n,&k);
  31.     for(int i = 1;i <= n;i++) scanf("%d",&s[i]);
  32.     dfs(1,0,0);
  33.     printf("%d",ans);
  34.     return 0;
  35. }
复制代码

回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
13#
发表于 2018-10-19 19:13:06 | 只看该作者
luogu P1123

取数游戏(差点做成网络流24。。)

因为周围8个不能取,所以从第一排第一列开始搜,剪枝只用判断左边和上边就ok,也是裸搜加一点点技巧

不知为何输出卡了半天。。

AC代码:
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. int n,m,t;
  4. int maps[1000][1000];
  5. int book[1000][1000];
  6. int s[1000];
  7. int ans = 0;

  8. void dfs(int sum,int x,int y)
  9. {
  10.     if(x > n)
  11.     {
  12.        ans = max(ans,sum);
  13.        return;
  14.     }
  15.     int tx = x;
  16.     int ty = y+1;
  17.     if(ty > m)
  18.     {
  19.         tx++;
  20.         ty = 1;
  21.     }
  22.     if(!book[x-1][y+1] && !book[x-1][y-1] && !book[x][y-1] && !book[x-1][y])
  23.     {
  24.         book[x][y] = 1;
  25.         dfs(sum+maps[x][y],tx,ty);
  26.         book[x][y] = 0;
  27.     }
  28.     dfs(sum,tx,ty);

  29. }


  30. int main()
  31. {
  32.     scanf("%d",&t);
  33.     while(t--)
  34.     {
  35.         ans = 0;
  36.         scanf("%d%d",&n,&m);
  37.         for(int i = 1;i <= n;i++)
  38.         {
  39.             for(int j = 1;j <= m;j++)
  40.             {
  41.                 scanf("%d",&maps[i][j]);
  42.             }
  43.         }
  44.         dfs(0,1,0);
  45.         printf("%d\n",ans);
  46.     }
  47.     return 0;
  48. }
复制代码

回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
14#
发表于 2018-10-19 19:17:10 | 只看该作者
luogu P1443 马的遍历

普及广搜

其实这题广搜确实比深搜简单,于是就广搜做了。。

把马八个方向先预处理一下,然后就是基本的广搜了。。弄一个变量更新最小值,跟走迷宫其实区别不大

AC代码:
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. struct note{
  4. int x;
  5. int y;

  6. };

  7. int maps[401][401];
  8. int k;
  9. int n,m,startx,starty;
  10. int s;
  11. int tx,ty;
  12. int i,j;
  13. int next[8][2] = {{2,1},{2,-1},{1,2},{1,-2},{-1,2},{-1,-2},{-2,1},{-2,-1}};
  14. int main()
  15. {
  16.     struct note que[40001];
  17.     memset(maps,-1,sizeof(maps));
  18.     int head = 1;
  19.     int tail = 1;
  20.     scanf("%d%d%d%d",&n,&m,&startx,&starty);
  21.     tail++;
  22.     que[tail].x = startx;
  23.     que[tail].y = starty;
  24.     maps[que[tail].x][que[tail].y] = 0;
  25.     while(head < tail)
  26.     {
  27.         head++;
  28.         s = maps[que[head].x][que[head].y] + 1;
  29.         for(k = 0;k < 8;k++)
  30.         {
  31.            tx = que[head].x + next[k][0]; ty = que[head].y + next[k][1];
  32.            if(maps[tx][ty] == -1 && tx >= 1 && tx <= n && ty >= 1 && ty <= m)
  33.            {
  34.                tail++;
  35.                que[tail].x = tx;
  36.                que[tail].y = ty;
  37.                maps[tx][ty] = s;
  38.            }
  39.         }

  40.     }
  41.     for(i = 1;i <= n;i++)
  42.     {
  43.         for(j = 1;j <= m;j++)
  44.         {
  45.             printf("%-5d",maps[i][j]);
  46.         }
  47.         printf("\n");
  48.     }

  49. return 0;
  50. }
复制代码

回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
15#
发表于 2018-10-19 19:20:08 | 只看该作者
luogu P2404 自然数的拆分问题

这题以前做过一个类似的。。。但到现在都有点没搞懂。。。

AC代码:
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. int s[1000] = {1};
  4. int n;
  5. int k;
  6. void print(int x)
  7. {
  8.     for(int i = 1;i < x;i++)
  9.     {
  10.         printf("%d+",s[i]);
  11.     }
  12.     printf("%d",s[x]);
  13.     printf("\n");
  14. }
  15. void dfs(int x)
  16. {
  17.     for(int i = s[x-1];i <= k;i++)
  18.     {
  19.         if(i == n) continue;
  20.         s[x] = i;
  21.         k -= i;
  22.         if(k == 0) print(x);
  23.         else dfs(x+1);

  24.         k+=i;
  25.     }
  26. }

  27. int main()
  28. {
  29.     scanf("%d",&n);
  30.     k = n;
  31.     dfs(1);
  32.     return 0;
  33. }
复制代码



回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
16#
发表于 2018-10-19 19:43:13 | 只看该作者
luogu P1238 走迷宫

3次才AC 第一次 50 第二次 80 第三次 100

分析原因:

1、上下左右看错????

2、初始位置要标记。。。

3、这其实就是一道水题。。。。

迷宫类型问题的基本套路,记得剪枝,不然要tle的。。

AC代码:
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. int maps[1000][1000];
  4. int book[1000][1000];
  5. int a[1000][3];
  6. int next[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
  7. int n,m;
  8. int flag;
  9. int p,q,sx,sy;
  10. void print(int x)
  11. {
  12.     for(int i = 1;i < x;i++)
  13.     {
  14.         printf("(%d,%d)->",a[i][1],a[i][2]);
  15.     }
  16.     printf("(%d,%d)",a[x][1],a[x][2]);
  17.     printf("\n");
  18. }
  19. void dfs(int x,int y,int step)
  20. {
  21.     int tx,ty;
  22.     if(x == p && y == q)
  23.     {
  24.         flag = 1;
  25.         print(step);
  26.         return;
  27.     }
  28.     for(int k = 0;k <= 3;k++)
  29.     {
  30.         tx = x + next[k][0];
  31.         ty = y + next[k][1];

  32.         if(tx < 1 || tx > n || ty < 1 || ty > m) continue;

  33.         if(book[tx][ty] == 0 && maps[tx][ty] == 1)
  34.         {
  35.             book[tx][ty] = 1;
  36.             a[step+1][1] = tx;
  37.             a[step+1][2] = ty;
  38.             dfs(tx,ty,step+1);
  39.             book[tx][ty] = 0;
  40.         }
  41.     }
  42. }
  43. int main()
  44. {
  45.     int i,j;
  46.     scanf("%d%d",&n,&m);
  47.     for(i = 1;i <= n;i++)
  48.     {
  49.         for(j = 1;j <= m;j++)
  50.         {
  51.             scanf("%d",&maps[i][j]);
  52.         }
  53.     }
  54.     scanf("%d%d",&sx,&sy);
  55.     scanf("%d%d",&p,&q);
  56.     a[1][1] = sx;
  57.     a[1][2] = sy;
  58.     book[sx][sy] = 1;
  59.     dfs(sx,sy,1);
  60.     if(flag == 0)
  61.     {
  62.         printf("-1");
  63.     }
  64.     return 0;
  65. }
复制代码

回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
17#
发表于 2018-10-26 19:23:28 | 只看该作者
luogu P1233 木棍加工

先排序,再寻找最大不上升序列

贪心思想。。。没用dp。
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. struct Mugun{
  4.     int l;
  5.     int w;
  6.     int book;
  7. }m[100000];

  8. int n;
  9. int ans = 0;

  10. int cmp(struct Mugun a,struct Mugun b)
  11. {
  12.     return a.l > b.l;
  13.     if(a.l == b.l)
  14.         return a.w > b.w;
  15. }
  16. int temp;
  17. int main()
  18. {
  19.     scanf("%d",&n);
  20.     for(int i = 1;i <= n;i++)
  21.     {
  22.         scanf("%d%d",&m[i].l,&m[i].w);
  23.         m[i].book = 0;
  24.     }
  25.     sort(m+1,m+1+n,cmp);
  26.     for(int i = 1;i <= n;i++)
  27.     {
  28.         if(m[i].book == 0)
  29.         {
  30.             temp = m[i].w;
  31.             for(int j = i+1;j <= n;j++)
  32.             {
  33.                 if(m[j].w<=temp&&m[j].book == 0)
  34.                 {
  35.                     m[j].book = 1;
  36.                     temp = m[j].w;
  37.                 }
  38.             }
  39.         }
  40.     }
  41.     for(int i = 1;i <= n;i++)
  42.     {
  43.         if(m[i].book == 0)
  44.         {
  45.             ans++;
  46.         }
  47.     }
  48.     printf("%d",ans);




  49.     return 0;
  50. }
复制代码

回复 支持 反对

使用道具 举报

23

主题

38

帖子

127

积分

华一学生

积分
127
18#
发表于 2018-10-26 19:24:47 | 只看该作者
luogu P1216 数字三角形

DP。。。吧
  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. int n,a[1002],i,j,ans,p;

  4. int main()
  5. {
  6.     scanf("%d",&n);
  7.         for(i=n;i;i--)
  8.                 for(j=i;j<=n;j++)
  9.                         scanf("%d",&p),a[j]=max(a[j],a[j+1])+p;
  10.         for(i=1;i<=n;i++)
  11.         ans=max(ans,a[i]);
  12.         printf("%d",ans);
  13.         return 0;
  14. }
复制代码



回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 02:39 , Processed in 0.208724 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表