第一题: tractor

题目描述
  农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上。FJ有一辆拖拉机,也在农场上。拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内。拖拉机的初始位置与所有草堆不同。
  FJ开拖拉机时,只能平行于坐标轴(即东、南、西、北四个方向),而且每次开动的一段必须是整数长度。
  例如,他可以向北开2个单位长度,然后向东开3个单位长度。拖拉机不能开到草堆的位置。
  请帮助FJ计算出最少要移动多少个草堆,他才能将拖拉机开回坐标原点。
  拖拉机可以开到1..1000之外的地方去。
输入
  第1行: 3个整数,即N 和拖拉机的初始位置 (x,y)
  第2..1+N行: 每行2个整数,表示一堆草的位置 (x,y)
输出
  第1行: FJ必须移动的最少的草堆的数量
样例输入
  7 6 3
  6 2
  5 2
  4 3
  2 1
  7 3
  5 4
  6 4
样例输出
  1


这道题:可以用BFS,DFS,SPFA,我选择了BFS。但是,我居然把BFS 的模板写错了。于是就死循环 了。就是vis数组的位置,一定要注意。然后剪枝很重要,我基本上能用到最优的剪枝:if (now.w>=ans) continue;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define maxn 1005
 7 using namespace std;
 8 const int zl[2][4]={{0,0,1,-1},{1,-1,0,0}};
 9 int n,xi,yi,ans=12345678;
10 bool mp[maxn][maxn],vis[maxn][maxn];
11 struct pp{
12     int x,y;
13     int w;
14 };
15 pp s;
16 queue < pp > q;
17 void bfs(int stx,int sty)
18 {
19     s.x=stx;
20     s.y=sty;
21     s.w=0;
22     vis[stx][sty]=true;//vis 的位置,bfs 模板....未掌握
23     q.push(s);
24     while (!q.empty())
25     {
26         pp cur=q.front();
27         //vis[cur.x][cur.y]=true;//注意在哪里加vis
28         q.pop();
29         for (int i=0;i<=3;i++)
30         {
31             int a=cur.x+zl[0][i],b=cur.y+zl[1][i];
32             if (vis[a][b]) continue;//否则死循环
33             pp now;
34             now.x=a;now.y=b;now.w=cur.w;
35             if (a<1||b<1||a>1000||b>1000){//到边界随便走
36                 if (cur.w<ans) ans=cur.w;
37                 continue;
38             }
39             if (a==0&&b==0){//到原点
40                 if (mp[a][b]) cur.w++;
41                 if (cur.w<ans) ans=cur.w;
42                 continue;
43             }
44             if (mp[a][b]) now.w++;
45             if (now.w>=ans) continue;//剪枝
46             vis[a][b]=true; //********
47             q.push(now);
48         }
49     }
50 }
51 int main()
52 {
53     freopen("tractor.in","r",stdin);
54     freopen("tractor.out","w",stdout);
55     cin>>n>>xi>>yi;
56     for (int i=1;i<=n;i++)
57     {
58         int x,y;
59         scanf("%d%d",&x,&y);
60         mp[x][y]=true;
61     }
62     bfs(xi,yi);
63     printf("%d",ans);
64     return 0;
65 }


第二题:Landscaping

题目描述
  N(1 <= N <= 100)个数排成一行,值分别为A_i,现在希望把每个数对应地改成B_i。(A_i,B_i的值均在0..10之间)。改变的方式有3种:
    (1)把A_i增加到B_i,每增加1,花费$X
    (2)把A_i减少到B_i,每减少1,花费$Y
    (3)把第i个数的值转移到第j个数,每转移1,花费为$Z*|i-j|
  问:最小的花费是多少。
输入
  第1行:4个整数 N, X, Y, Z (0 <= X, Y, Z <= 1000).
  第2..1+N行: 每行2个整数 A_i 和 B_i.
输出
  第1行:1个整数,表示最小的花费。
样例输入
  4 100 200 1
  1 4
  2 3
  3 2
  4 0
样例输出
  210


解:

  考试的时候用的贪心,过了50分剩下的T了,好像大家感到很惊讶。这个贪心,有点神奇。记录最近的方向(即是需要+,还是-)相同和方向相反的点,方向相同的是方便传递。然后转移最近的。最后剩的就是自己+,-了。

  然后这道题是一道DP题。类似于均分纸牌。f[i][j]表示前 i 个数交换 j 个1 的最小花费。

  具体的解释在代码里了。这道DP的思想很重要。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 105
 6 using namespace std;
 7 int n,x,y,z,base=1000,v;
 8 int cha[maxn],dp[maxn][2005];
 9 int main()
10 {
11     freopen("landscaping.in","r",stdin);
12     freopen("landscaping.out","w",stdout);
13     cin>>n>>x>>y>>z;
14     for (int i=1;i<=n;i++)
15     {
16         int a,b;
17         scanf("%d%d",&a,&b);
18         cha[i]=b-a;//need how much:b-a not a-b
19         v+=abs(cha[i]);//abs
20     }
21     memset(dp,0x3f,sizeof(dp));//赋初值
22     dp[0][base]=0;
23     for (int i=0;i<n;i++)
24     {
25         for (int j=-v;j<=v;j++)//所有状态
26           dp[i+1][base+j+cha[i+1]]=min(dp[i+1][base+j+cha[i+1]],dp[i][base+j]+z*abs(j));//abs(j)
27           //前i个人需要j个,所以用i+1给i j个,i+1就需要 j+cha[i+1]个
28           //从最后一个人考虑,则刚好前n-1 个人需要的j个 与cha[n]抵消,(类似于均分纸牌)
29         if (cha[i+1]>0){//自己加
30             for (int j=v;j>=1;j--)
31                   dp[i+1][base+j-1]=min(dp[i+1][base+j-1],dp[i+1][base+j]+x);
32         }
33         else {//自己减
34             for (int j=-v;j<=-1;j++)
35                   dp[i+1][base+j+1]=min(dp[i+1][base+j+1],dp[i+1][base+j]+y);
36         }
37     }
38     printf("%d",dp[n][base]);
39     return 0;
40 }


第三题“:equal

【问题描述】
  明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
  这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
  这个选择题中的每个表达式都满足下面的性质:
    1. 表达式只可能包含一个变量‘a’。
    2. 表达式中出现的数都是正整数,而且都小于10000。
    3. 表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘^’,然后是‘*’,最后   是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)    
    4. 幂指数只可能是1到10之间的正整数(包括1和10)。
    5. 表达式内部,头部或者尾部都可能有一些多余的空格。  
  下面是一些合理的表达式的例子:
    ((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9……


这道题是noip的某第三道题。由于把多项式展开太复杂,所以我们用类似于多项式计算的方式,把a替代为一个很大的素数,并且计算时mod上一个素数,然后看选项计算的值是否与第一个表达式相同。

表达式的计算,这个模板还需要练。乘方的优先级是最高的需要注意它的判断。乘方用快速幂写。

还有读入:因为要舍去空格,所以建议一个一个的读入。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<map>
  6 #define maxn 55
  7 #define ll long long
  8 using namespace std;
  9 const ll P[]={10003,10007,56971},Q[]={2,73217,33233};
 10 int n;
 11 ll ans[5];
 12 char s[maxn],symbol[maxn];
 13 ll num[maxn];
 14 int topn,topf;
 15 void read_string()
 16 {
 17     int l=0;
 18     char c=getchar();
 19     while (c==' '||c=='\n') c=getchar();
 20     while (c!='\n'&&c!=EOF)
 21     {
 22         if (c!=' ') s[++l]=c;
 23         c=getchar();
 24     }
 25     s[0]='(';s[++l]=')';
 26 }
 27 ll ksm(ll a,ll b,ll modd)
 28 {
 29     ll t=1,tmp=a;
 30     while (b>0)
 31     {
 32         if (b%2) t=(tmp*t)%modd;
 33         b=b>>1;
 34         tmp=(tmp*tmp)%modd;
 35     }
 36     return t;
 37 }
 38 void pop(ll modd)
 39 {
 40     switch(symbol[topf])
 41     {
 42         case'+':num[topn-1]=(num[topn]+num[topn-1])%modd;topn--;break;
 43         case'-':num[topn-1]=((num[topn-1]-num[topn])%modd+modd)%modd;topn--;break;
 44         case'*':num[topn-1]=(num[topn-1]*num[topn])%modd;topn--;break;
 45         case'^':num[topn-1]=ksm(num[topn-1],num[topn],modd)%modd;topn--;break;
 46     }
 47     topf--;
 48 }
 49 bool pd(int i)
 50 {
 51     if ((s[i]=='+'||s[i]=='-')&&symbol[topf]!='(') return true;
 52     if (symbol[topf]=='^') return true;//^的优先级最高
 53     if ((s[i]=='*'&&symbol[topf]=='*')) return true;
 54     return false;
 55 }
 56 ll js(int tt)
 57 {
 58     int i=0,len=strlen(s);
 59     while (i<len)
 60     {
 61         while (s[i]=='(') {
 62             symbol[++topf]=s[i];
 63             i++;
 64         }
 65         ll x=0;
 66         if (s[i]=='a'){
 67             x=Q[tt];i++;
 68         }
 69         else {
 70             while (s[i]>='0'&&s[i]<='9')
 71               x=x*10+s[i++]-'0';
 72         }
 73         num[++topn]=x;
 74         do{
 75             if (s[i]==')'){
 76                 while (symbol[topf]!='(') pop(P[tt]);
 77                 topf--;//删括号 *******
 78             }
 79             else{
 80                 while (pd(i)) pop(P[tt]);
 81                 symbol[++topf]=s[i];
 82             }
 83             i++;
 84         }while (i<strlen(s)&&s[i-1]==')');
 85     }
 86     return num[1];
 87 }
 88 int main()
 89 {
 90     freopen("equal.in","r",stdin);
 91     freopen("equal.out","w",stdout);
 92     read_string();//gets 的使用
 93     for (int i=0;i<=2;i++)
 94     {
 95         memset(symbol,0,sizeof(symbol));
 96         memset(num,0,sizeof(num));
 97         topn=0;topf=0;
 98         ans[i]=js(i);
 99     }
100     cin>>n;
101     getchar();//getchar
102     for (int i=1;i<=n;i++)
103     {
104         memset(s,0,sizeof(s));
105         read_string();
106         bool b=false;
107         for (int j=0;j<=2;j++)
108         {
109             memset(symbol,0,sizeof(symbol));
110             memset(num,0,sizeof(num));
111             topn=0;topf=0;
112             ll cur=js(j);
113             if (cur!=ans[j]) {
114                 b=true;
115                 break;
116             }
117         }
118         if (b) continue;
119         char oo='A'+i-1;
120         printf("%c",oo);
121     }
122     return 0;
123 }

转载于:https://www.cnblogs.com/lx0319/p/6059912.html

【63测试20161111】【BFS】【DP】【字符串】相关推荐

  1. HDU3247 Resource Archiver(AC自动机+BFS+DP)

    题目,求最短的包含所有n个DNA片段且不包含任何一个病毒片段的序列. 容易用所有DNA片段和病毒片段建一个AC自动机,构造fail时处理一下各个结点后缀是DNA或者病毒的情况,然后dp[S][u]表示 ...

  2. POJ 2817 状态DP 字符串找最多的重复

    题意: 给出字符串个数 n 给出n串字符串 找出上下两个字符串重复和最多的个数.. eg: 5 abc bcd cde aaa bfcde 0根据 aaa abc bcd cde bfcde答案就是重 ...

  3. 蓝桥杯 算法训练 Cowboys By Assassin dp+字符串操作

    问题描述一个间不容发的时刻:n个牛仔站立于一个环中,并且每个牛仔都用左轮手枪指着他旁边的人!每个牛仔指着他顺时针或者逆时针方向上的相邻的人.正如很多西部片那样,在这一刻,绳命是入刺的不可惜--对峙的场 ...

  4. hdu 5433(bfs+dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5433 解题思路: dp[i][j][k]表示在(x,y)点,毅力为k时的最小体力.由于每个点可能会走多 ...

  5. leetcode542. 01 矩阵(bfs/dp)

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...

  6. LeetCode 542. 01 矩阵(BFS DP)

    文章目录 1. 题目 2. 解题 2.1 BFS 2.2 DP动态规划 1. 题目 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: ...

  7. 动态规划 —— 线性 DP —— 字符串编辑距离

    [概述] 字符串编辑距离,即 Levenshtein 距离,是俄国科学家 Vladimir Levenshtein 提出的概念,是指从一个字符串修改到另一个字符串时,编辑单个字符所需的最少次数,编辑单 ...

  8. hdu 1159(DP+字符串最长公共序列)

    http://blog.csdn.net/a_eagle/article/details/7213236 公共序列可以用一个二维数组dp[i][j]保存每个点时的最大数字,本质就是一个双向比较. dp ...

  9. DFS和BFS求字符串的所有非空子集———Java

    二进制法省略,因其不能求长字符串的子集 1. BFS -- 比DFS高效,推荐 import java.util.*;public class Main{static HashSet<Strin ...

  10. CodeForces - 1422E Minlexes(dp+字符串)

    题目链接:点击查看 题目大意:对一个长度为 n 的字符串 s 来说,可以进行的操作如下: 选出一个二元对 ( i , i + 1 ) 满足 i >= 0 && i + 1 < ...

最新文章

  1. 数据库迁移用到的命令
  2. Exchange 2013/2016动态通讯组成员查询
  3. 您能否提供一些示例,说明为什么用正则表达式很难解析XML和HTML? [关闭]
  4. gulp html页面路径,配置gulp前端开发环境
  5. Docker阿里云镜像存储服务
  6. mysql percona server_MySQL Study之--Percona Server版本
  7. 7、实例:计算课程结束的日期
  8. Python tcp编程,TCP服务端和TCP客户端代码编写
  9. 【Linux】一步一步学Linux——systemctl命令(147)
  10. 【手机游戏开发优化篇】详解手游[体积]及[运行内存]的优化篇!
  11. 店招模块终于可以进行后台换图片了
  12. 修改 VS2013 项目属性的默认包含路径(全局)
  13. 北京大学:“巍巍上庠 国运所系”北大为时代发展而歌(附历年高考各省投档线)...
  14. java 封装(Encapsulation)
  15. 西方主要管理思想简介
  16. DATAGUARD 添加修改REDOLOG大小
  17. python各个版本区别_Python 的各个版本
  18. 俄罗斯方块java分析_[源码和文档分享]基于Java的俄罗斯方块游戏
  19. android 5.1 改mac地址,mac地址可以随便改吗
  20. VB DoEvents用法

热门文章

  1. 谈提高健身效果的营养品系列之一: 乳清蛋白, 肌酸, 支链氨基酸
  2. Matlab---示波器Scope-Measurements
  3. POJ - 1679 The Unique MST (次小生成树) 板子
  4. c语言中元音字母对应的的值,c语言输入一个字符串,统计这个字符串的元音字母...
  5. 三星android 安卓版本怎么升级包,三星A70官方安卓9固件系统线刷升级更新包:BRI-A7050ZHU3ASJ1...
  6. 【Week7 作业B】TT的旅行日记
  7. 【Swift】401状态处理流程
  8. H3C网络设备模拟器显示交换机的MAC地址表
  9. Linux用户家目录与根目录
  10. 计算机管理属性被禁用,win7命令提示符提示已被系统管理员停用?