第一题: 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;

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 1005
using namespace std;
const int zl[][]={{,,,-},{,-,,}};
int n,xi,yi,ans=;
bool mp[maxn][maxn],vis[maxn][maxn];
struct pp{
int x,y;
int w;
};
pp s;
queue < pp > q;
void bfs(int stx,int sty)
{
s.x=stx;
s.y=sty;
s.w=;
vis[stx][sty]=true;//vis 的位置,bfs 模板....未掌握
q.push(s);
while (!q.empty())
{
pp cur=q.front();
//vis[cur.x][cur.y]=true;//注意在哪里加vis
q.pop();
for (int i=;i<=;i++)
{
int a=cur.x+zl[][i],b=cur.y+zl[][i];
if (vis[a][b]) continue;//否则死循环
pp now;
now.x=a;now.y=b;now.w=cur.w;
if (a<||b<||a>||b>){//到边界随便走
if (cur.w<ans) ans=cur.w;
continue;
}
if (a==&&b==){//到原点
if (mp[a][b]) cur.w++;
if (cur.w<ans) ans=cur.w;
continue;
}
if (mp[a][b]) now.w++;
if (now.w>=ans) continue;//剪枝
vis[a][b]=true; //********
q.push(now);
}
}
}
int main()
{
freopen("tractor.in","r",stdin);
freopen("tractor.out","w",stdout);
cin>>n>>xi>>yi;
for (int i=;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
mp[x][y]=true;
}
bfs(xi,yi);
printf("%d",ans);
return ;
}

第二题: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的思想很重要。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 105
using namespace std;
int n,x,y,z,base=,v;
int cha[maxn],dp[maxn][];
int main()
{
freopen("landscaping.in","r",stdin);
freopen("landscaping.out","w",stdout);
cin>>n>>x>>y>>z;
for (int i=;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
cha[i]=b-a;//need how much:b-a not a-b
v+=abs(cha[i]);//abs
}
memset(dp,0x3f,sizeof(dp));//赋初值
dp[][base]=;
for (int i=;i<n;i++)
{
for (int j=-v;j<=v;j++)//所有状态
dp[i+][base+j+cha[i+]]=min(dp[i+][base+j+cha[i+]],dp[i][base+j]+z*abs(j));//abs(j)
//前i个人需要j个,所以用i+1给i j个,i+1就需要 j+cha[i+1]个
//从最后一个人考虑,则刚好前n-1 个人需要的j个 与cha[n]抵消,(类似于均分纸牌)
if (cha[i+]>){//自己加
for (int j=v;j>=;j--)
dp[i+][base+j-]=min(dp[i+][base+j-],dp[i+][base+j]+x);
}
else {//自己减
for (int j=-v;j<=-;j++)
dp[i+][base+j+]=min(dp[i+][base+j+],dp[i+][base+j]+y);
}
}
printf("%d",dp[n][base]);
return ;
}

第三题“: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上一个素数,然后看选项计算的值是否与第一个表达式相同。

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

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

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define maxn 55
#define ll long long
using namespace std;
const ll P[]={,,},Q[]={,,};
int n;
ll ans[];
char s[maxn],symbol[maxn];
ll num[maxn];
int topn,topf;
void read_string()
{
int l=;
char c=getchar();
while (c==' '||c=='\n') c=getchar();
while (c!='\n'&&c!=EOF)
{
if (c!=' ') s[++l]=c;
c=getchar();
}
s[]='(';s[++l]=')';
}
ll ksm(ll a,ll b,ll modd)
{
ll t=,tmp=a;
while (b>)
{
if (b%) t=(tmp*t)%modd;
b=b>>;
tmp=(tmp*tmp)%modd;
}
return t;
}
void pop(ll modd)
{
switch(symbol[topf])
{
case'+':num[topn-]=(num[topn]+num[topn-])%modd;topn--;break;
case'-':num[topn-]=((num[topn-]-num[topn])%modd+modd)%modd;topn--;break;
case'*':num[topn-]=(num[topn-]*num[topn])%modd;topn--;break;
case'^':num[topn-]=ksm(num[topn-],num[topn],modd)%modd;topn--;break;
}
topf--;
}
bool pd(int i)
{
if ((s[i]=='+'||s[i]=='-')&&symbol[topf]!='(') return true;
if (symbol[topf]=='^') return true;//^的优先级最高
if ((s[i]=='*'&&symbol[topf]=='*')) return true;
return false;
}
ll js(int tt)
{
int i=,len=strlen(s);
while (i<len)
{
while (s[i]=='(') {
symbol[++topf]=s[i];
i++;
}
ll x=;
if (s[i]=='a'){
x=Q[tt];i++;
}
else {
while (s[i]>=''&&s[i]<='')
x=x*+s[i++]-'';
}
num[++topn]=x;
do{
if (s[i]==')'){
while (symbol[topf]!='(') pop(P[tt]);
topf--;//删括号 *******
}
else{
while (pd(i)) pop(P[tt]);
symbol[++topf]=s[i];
}
i++;
}while (i<strlen(s)&&s[i-]==')');
}
return num[];
}
int main()
{
freopen("equal.in","r",stdin);
freopen("equal.out","w",stdout);
read_string();//gets 的使用
for (int i=;i<=;i++)
{
memset(symbol,,sizeof(symbol));
memset(num,,sizeof(num));
topn=;topf=;
ans[i]=js(i);
}
cin>>n;
getchar();//getchar
for (int i=;i<=n;i++)
{
memset(s,,sizeof(s));
read_string();
bool b=false;
for (int j=;j<=;j++)
{
memset(symbol,,sizeof(symbol));
memset(num,,sizeof(num));
topn=;topf=;
ll cur=js(j);
if (cur!=ans[j]) {
b=true;
break;
}
}
if (b) continue;
char oo='A'+i-;
printf("%c",oo);
}
return ;
}

【63测试20161111】【BFS】【DP】【字符串】的更多相关文章

  1. 【2019.8.14 慈溪模拟赛 T1】我不是!我没有!别瞎说啊!(notme)(BFS+DP)

    \(IDA^*\) 说实话,这道题我一开始没想出正解,于是写了一个\(IDA^*\)... 但神奇的是,这个\(IDA^*\)居然连字符串长度分别为\(2500,4000\)的数据都跑得飞快,不过数据 ...

  2. ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

    这是一道非常好的题目,融合了很多知识点. ZOJ1232-Adventrue of Super Mario 这一题折磨我挺长时间的,不过最后做出来非常开心啊,哇咔咔咔 题意就不累述了,注释有写,难点在 ...

  3. ZOJ 3596Digit Number(BFS+DP)

    一道比较不错的BFS+DP题目 题意很简单,就是问一个刚好包含m(m<=10)个不同数字的n的最小倍数. 很明显如果直接枚举每一位是什么这样的话显然复杂度是没有上限的,所以需要找到一个状态表示方 ...

  4. 6-3 bash脚本编程之五 字符串测试及for循环

    1. 字符测试 ==:等号两边要有空格,否则会被认为是赋值. !=:  测试是否相等,记住如果不等为真,等为假. -n string: 测试指定字符串是否为空,空位真,不空为假. -s string: ...

  5. 【65测试20161114】【字符串】【DP】

    第一题 复制&粘贴: 文件的内容是一个字符串S,对其进行N次复制&粘贴的操作,第i次操作复制位置Ai和位置Bi之间的所有文字,然后在位置Ci粘贴.这里位置x表示字符串的第x个字符的后面 ...

  6. UVALive 5066 Fire Drill --BFS+DP

    题意:有一个三维的地图,有n个人被困住,现在消防队员只能从1楼的一个入口进入,营救被困者,每一个被困者有一个价值,当消防队员找到一个被困者之后,他可以营救或者见死不救,如果救的话,他必须马上将其背到入 ...

  7. AOJ 0121: Seven Puzzle (BFS DP STL 逆向推理)(转载)

    转载自:  http://m.blog.csdn.net/blog/Enjoying_Science/42008801 题目链接:http://acm.hust.edu.cn/vjudge/probl ...

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

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

  9. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

随机推荐

  1. gradle手工搭建java项目搭建

    1. 安装gradle. 下载http://services.gradle.org/distributions/gradle-1.9-all.zip,解压至/usr/local/目录下. 设置环境变量 ...

  2. javascript百度地图添加一个普通标注点(2014-3-8 记)

    1.导入jquery.js文件:<script type="text/javascript" src="js/jquery.js"></scr ...

  3. 本地yum库制作及本地安装Docker

    生产环境中,我们总是会遇到服务器无法连接外网的情况,这样,如果想安装某个应用,而这个应用依赖的其他类库又特别多,就很痛苦了.这个时候,就需要自己制作个本地的yum库,进行本地安装.本文将以Docker ...

  4. lucene5.5 field

    lucene常见Field IntField 主要对int类型的字段进行存储,需要注意的是如果需要对InfField进行排序使用SortField.Type.INT来比较,如果进范围查询或过滤,需要采 ...

  5. Asp.Net在多线程环境下的状态存储问题

    在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...

  6. libevent源码分析(一)

    分析libevent的源代码,我的想法的是先分析各种结构体,struct event_base.struct event,然后是event_base_new函数.event_new函数.event_a ...

  7. ipad开发:二维码扫描,摄像头旋转角度问题解决办法

    之前一直是在手机上开发,用系统原生二维码扫描功能,一点问题都没有,但是在ipad上,用户是横屏操作的,虽然界面旋转了,是横屏的,但是摄像头里显示的依然是竖屏效果,也就是说从摄像头里看到的和人眼看到的内 ...

  8. [问题2014A13] 解答

    [问题2014A13]  解答 先引入两个简单的结论. 结论 1  设 \(\varphi\) 是 \(n\) 维线性空间 \(V\) 上的线性变换, 若存在正整数 \(k\), 使得 \(\math ...

  9. ReactiveCocoa(RAC)

    好处:代码高聚合,方便我们管理: 链式编程: CaculatorMaker.h #import <Foundation/Foundation.h> #define ADD #define ...

  10. JS事件委托学习(转)

    JS 事件委托就是利用冒泡原理,把事件加到父级上触发,执行效果. 好处: 1.提高性能 2.新添加的元素还会有之前的事件     <</</</</li></ ...