华师一附中OI组

标题: 刘伟杰李香来程序大楼 [打印本页]

作者: admin    时间: 2018-10-16 19:03
标题: 刘伟杰李香来程序大楼
这是刘,李两位同学的程序暂存大楼,他们的程序写在这里,自己欣赏
作者: 刘伟杰    时间: 2018-10-16 21:04
本帖最后由 刘伟杰 于 2018-10-16 21:07 编辑

luogu p1095 守望者的逃离 水题

思路:dp+贪心

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

  2. using namespace std;

  3. int dp[15000000];
  4. int m,s,t;


  5. int main()
  6. {
  7.    scanf("%d%d%d",&m,&s,&t);
  8.    int i;
  9.    for(i = 1;i <= t;i++)
  10.    {
  11.        if(m >= 10)
  12.        {
  13.            m -= 10;
  14.            dp[i] = dp[i-1] + 60;
  15.        }else
  16.        {
  17.            m+=4;
  18.            dp[i] = dp[i-1];
  19.        }
  20.    }
  21.    for(i = 1;i <= t;i++)
  22.    {
  23.        dp[i] = max(dp[i-1]+17,dp[i]);
  24.        if(dp[i] >= s)
  25.        {
  26.            printf("Yes\n%d",i);
  27.            return 0;
  28.        }
  29.    }
  30.    printf("No\n%d",dp[t]);

  31.     return 0;
  32. }
复制代码



作者: 刘伟杰    时间: 2018-10-16 21:06
luogu p1098 字符串展开 模拟

特判比较多

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

  2. using namespace std;

  3. char a[100000];
  4. int p1,p2,p3;
  5. char bg;
  6. char ed;
  7. int main()
  8. {

  9.     scanf("%d%d%d",&p1,&p2,&p3);
  10.     scanf("%s",a);
  11.     int len = strlen(a);
  12.     for(int i = 0;i < len;i++)
  13.     {
  14.         if(a[i] != '-')
  15.         {
  16.             printf("%c",a[i]);
  17.         }else
  18.         {
  19.             if(a[i-1] == '-')
  20.             {
  21.                 printf("-");
  22.                 continue;
  23.             }
  24.             if(a[i-1] >= a[i+1])
  25.             {
  26.                 printf("-");
  27.                 continue;
  28.             }
  29.             if(a[i+1] - a[i-1]> 27)
  30.             {
  31.                 printf("-");
  32.                 continue;
  33.             }
  34.             if(a[i+1] - a[i-1] == 1)  continue;
  35.             if(p1 == 1)
  36.             {
  37.                 if(p3 == 2)
  38.                 {
  39.                    ed = a[i-1] + 1;
  40.                    bg = a[i+1] - 1;
  41.                    for(int j = bg;j >= ed;j--)
  42.                    {
  43.                        char z = j;
  44.                        for(int k = 1;k <= p2;k++)
  45.                        {
  46.                            printf("%c",z);
  47.                        }
  48.                    }
  49.                 }else
  50.                 {
  51.                    bg = a[i-1] + 1;
  52.                    ed = a[i+1] - 1;
  53.                    for(int j = bg;j <= ed;j++)
  54.                    {
  55.                        char z = j;
  56.                        for(int k = 1;k <= p2;k++)
  57.                        {
  58.                            printf("%c",z);
  59.                        }
  60.                    }
  61.                 }
  62.             }
  63.             if(p1 == 3)
  64.             {
  65.                 if(p3 == 2)
  66.                 {
  67.                    ed = a[i-1] + 1;
  68.                    bg = a[i+1] - 1;
  69.                    for(int j = bg;j >= ed;j--)
  70.                    {
  71.                        for(int k = 1;k <= p2;k++)
  72.                        {
  73.                            printf("*");
  74.                        }
  75.                    }
  76.                 }else
  77.                 {
  78.                    bg = a[i-1] + 1;
  79.                    ed = a[i+1] - 1;
  80.                    for(int j = bg;j <= ed;j++)
  81.                    {
  82.                        for(int k = 1;k <= p2;k++)
  83.                        {
  84.                            printf("*");
  85.                        }
  86.                    }
  87.                 }
  88.             }
  89.             if(p1 == 2)
  90.             {
  91.                 if(p3 == 2)
  92.                 {
  93.                    ed = a[i-1] + 1;
  94.                    bg = a[i+1] - 1;
  95.                    for(int j = bg;j >= ed;j--)
  96.                    {
  97.                        char z = j;
  98.                        if(z > 96)
  99.                        {
  100.                            z = z - 32;
  101.                        }
  102.                        for(int k = 1;k <= p2;k++)
  103.                        {
  104.                            printf("%c",z);
  105.                        }
  106.                    }
  107.                 }else
  108.                 {
  109.                    bg = a[i-1] + 1;
  110.                    ed = a[i+1] - 1;
  111.                    for(int j = bg;j <= ed;j++)
  112.                    {
  113.                        char z = j;
  114.                        if(z > 96)
  115.                        {
  116.                            z = z - 32;
  117.                        }
  118.                        for(int k = 1;k <= p2;k++)
  119.                        {
  120.                            printf("%c",z);
  121.                        }
  122.                    }
  123.                 }
  124.             }
  125.         }
  126.     }

  127.     return 0;
  128. }
复制代码



作者: 刘伟杰    时间: 2018-10-16 21:19
luogu UVA253 cube painting
穷举 可以用到数学思想:不管骰子怎么转动,相对的两面不变。

穷举AC代码:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int dir[6][6] = { { 0, 1, 2, 3, 4, 5 }, { 1, 0, 3, 2, 5, 4 }, { 2, 0, 1, 4, 5, 3 }, { 3, 0, 4, 1, 5, 2 }, { 4, 0, 2, 3, 5, 1 }, { 5, 1, 3, 2, 4, 0 } };
  4. char a[10],b[10],s[20];
  5. bool judge()
  6. {
  7.     for (int i=0; i<6; i++)
  8.     {
  9.         char temp[10]="";
  10.         for (int j=0; j<6; j++)
  11.             temp[j]=a[dir[i][j]];
  12.         for (int j=0; j<4; j++)
  13.         {
  14.             char c_temp;
  15.             c_temp=temp[1];
  16.             temp[1]=temp[2];
  17.             temp[2]=temp[4];
  18.             temp[4]=temp[3];
  19.             temp[3]=c_temp;
  20.             if (strcmp(temp,b)==0) return true;
  21.         }
  22.     }
  23.     return false;
  24. }
  25. int main()
  26. {
  27.     while (scanf("%s",s)!=EOF)
  28.     {
  29.         for (int i=0; i<6; i++)
  30.             a[i]=s[i];
  31.         a[6]=0;
  32.         for (int i=0; i<6; i++)
  33.             b[i]=s[i+6];
  34.         b[6]=0;
  35.         if (judge()) printf("TRUE\n");
  36.         else printf("FALSE\n");
  37.     }
  38. }
复制代码


作者: 刘伟杰    时间: 2018-10-16 21:26
luogu p1598 垂直柱状图   
过水,注意输出
模拟
AC代码:
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. string k[10];
  4. int m;
  5. int len[5];
  6. int counts[27];
  7. int ans;
  8. void f(int x)
  9. {
  10.     int i;
  11.     for(i = 0; i < len[x]; i++)
  12.     {
  13.         if(k[x][i] == 'A') counts[1]++;
  14.         if(k[x][i] == 'B') counts[2]++;
  15.         if(k[x][i] == 'C') counts[3]++;
  16.         if(k[x][i] == 'D') counts[4]++;
  17.         if(k[x][i] == 'E') counts[5]++;
  18.         if(k[x][i] == 'F') counts[6]++;
  19.         if(k[x][i] == 'G') counts[7]++;
  20.         if(k[x][i] == 'H') counts[8]++;
  21.         if(k[x][i] == 'I') counts[9]++;
  22.         if(k[x][i] == 'J') counts[10]++;
  23.         if(k[x][i] == 'K') counts[11]++;
  24.         if(k[x][i] == 'L') counts[12]++;
  25.         if(k[x][i] == 'M') counts[13]++;
  26.         if(k[x][i] == 'N') counts[14]++;
  27.         if(k[x][i] == 'O') counts[15]++;
  28.         if(k[x][i] == 'P') counts[16]++;
  29.         if(k[x][i] == 'Q') counts[17]++;
  30.         if(k[x][i] == 'R') counts[18]++;
  31.         if(k[x][i] == 'S') counts[19]++;
  32.         if(k[x][i] == 'T') counts[20]++;
  33.         if(k[x][i] == 'U') counts[21]++;
  34.         if(k[x][i] == 'V') counts[22]++;
  35.         if(k[x][i] == 'W') counts[23]++;
  36.         if(k[x][i] == 'X') counts[24]++;
  37.         if(k[x][i] == 'Y') counts[25]++;
  38.         if(k[x][i] == 'Z') counts[26]++;

  39.     }
  40. }

  41. int main()
  42. {
  43.     for(int i = 1; i <= 4; i++)
  44.     {
  45.         getline(cin,k[i]);
  46.         len[i] = k[i].size();
  47.     }
  48.     for(int i = 1; i <= 4; i++)
  49.     {
  50.         f(i);
  51.     }
  52.     for(int i = 1; i <= 26; i++)
  53.     {
  54.         ans = max(ans,counts[i]);
  55.     }
  56.     m = ans;
  57.     for(int i = 1; i <= ans; i++)
  58.     {
  59.         for(int j = 1; j <= 26; j++)
  60.         {
  61.             if(counts[j] >= m)
  62.             {
  63.                 printf("* ");
  64.             }
  65.             else
  66.             {
  67.                 printf("  ");
  68.             }
  69.         }
  70.         m--;
  71.         printf("\n");
  72.     }
  73.     printf("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");


  74.     return 0;
  75. }
复制代码

作者: admin    时间: 2018-10-17 09:51
楼上的此题函数f应该用数组直接跳转
作者: 刘伟杰    时间: 2018-10-17 18:55
luogu P1691 有重复元素的排列问题
我绝对不会说我是用stl的

下面附上AC代码:

  1. #include <bits/stdc++.h>

  2. using namespace std;

  3. char s1[1000];
  4. char s2[1000];
  5. int ans;
  6. int main()
  7. {
  8.     int n;
  9.     scanf("%d",&n);
  10.     scanf("%s",s1);
  11.     sort(s1,s1+n);
  12.     do{
  13.         for(int i = 0;i < n;i++)
  14.         {
  15.             printf("%c",s1[i]);
  16.         }
  17.         ans++;
  18.         printf("\n");
  19.     }while(next_permutation(s1,s1+n));
  20.     printf("%d",ans);
  21.     return 0;
  22. }
复制代码



作者: 刘伟杰    时间: 2018-10-17 19:14
本帖最后由 刘伟杰 于 2018-10-17 19:25 编辑

luogu P1706 全排列问题

其实我是特别想用stl的

方法:裸dfs就ok

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

  2. using namespace std;

  3. int a[100];
  4. int book[100];
  5. int n;
  6. void print()
  7. {
  8.     for(int i = 1;i <= n;i++)
  9.     {
  10.         printf("%5d",a[i]);
  11.     }
  12.     printf("\n");
  13. }
  14. void dfs(int x)
  15. {
  16.     if(x == n+1)
  17.     {
  18.         print();
  19.         return;
  20.     }
  21.     for(int i = 1;i <= n;i++)
  22.     {
  23.         if(book[i] == 0)
  24.         {
  25.             book[i] = 1;
  26.             a[x] = i;
  27.             dfs(x+1);
  28.             book[i] = 0;
  29.         }
  30.     }
  31. }


  32. int main()
  33. {
  34.     scanf("%d",&n);
  35.     dfs(1);
  36.     return 0;
  37. }
复制代码


作者: 刘伟杰    时间: 2018-10-17 19:15
本帖最后由 刘伟杰 于 2018-10-17 19:26 编辑

luogu P1157 组合的输出

这跟全排列有区别吗。。。有一点吧

裸dfs

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

  2. using namespace std;

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

  23.     for(int i = a[x-1];i <= n;i++)
  24.     {
  25.         if(book[i] == 0)
  26.         {
  27.             book[i] = 1;
  28.             a[x] = i;
  29.             dfs(x+1);
  30.             book[i] = 0;
  31.         }
  32.     }
  33. }


  34. int main()
  35. {
  36.     scanf("%d%d",&n,&k);
  37.     a[0] = 1;
  38.     dfs(1);
  39.     return 0;
  40. }
复制代码



作者: 刘伟杰    时间: 2018-10-17 19:17
刘伟杰 发表于 2018-10-17 18:55
luogu P1691 有重复元素的排列问题
我绝对不会说我是用stl的

其实应该用搜索的,我错了
作者: admin    时间: 2018-10-18 11:53
刘伟杰 发表于 2018-10-17 19:17
其实应该用搜索的,我错了

这个很有用,也需要掌握!
作者: 刘伟杰    时间: 2018-10-19 19:10
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. }
复制代码


作者: 刘伟杰    时间: 2018-10-19 19:13
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. }
复制代码


作者: 刘伟杰    时间: 2018-10-19 19:17
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. }
复制代码


作者: 刘伟杰    时间: 2018-10-19 19:20
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. }
复制代码




作者: 刘伟杰    时间: 2018-10-19 19:43
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. }
复制代码


作者: 刘伟杰    时间: 2018-10-26 19:23
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. }
复制代码


作者: 刘伟杰    时间: 2018-10-26 19:24
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. }
复制代码








欢迎光临 华师一附中OI组 (http://hsyit.cn/) Powered by Discuz! X3.2