[题解]某模拟题(USACO月赛部分题+noip2005部分题)
题目描述
农场上有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必须移动的最少的草堆的数量
样例输入
样例输出
1
提示
样例说明:拖拉机初始在(6,3),7堆草分别在 (6,2), (5,2), (4,3), (2,1), (7,3), (5,4), (6,4).
FJ必须移动一堆草
水题,不多说,spfa跑到边界就可以了,只不过由于我比较懒,所以还是让它跑到原点
Code
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != -);
if(x == -){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class Point{
public:
int x;
int y;
Point(const int x = , const int y = ):x(x), y(y){ }
}Point; const int mover[][] = {{, , -, }, {, , , -}}; int n;
int sx, sy;
int bx, by;
int f[][];
boolean cd[][];
boolean inque[][];
boolean visited[][]; boolean isExeeded(Point& p){
if(p.x < || p.y < ) return true;
if(p.x > bx || p.y > by) return true;
return false;
} queue<Point> que;
inline int spfa(){
que.push(Point(sx, sy));
visited[sx][sy] = true;
inque[sx][sy] = true;
while(!que.empty()){
Point e = que.front();
que.pop();
inque[e.x][e.y] = false;
for(int k = ; k < ; k++){
Point eu(e.x + mover[][k], e.y + mover[][k]);
if(isExeeded(eu)) continue;
if(f[e.x][e.y] + cd[e.x][e.y] < f[eu.x][eu.y] || !visited[eu.x][eu.y]){
visited[eu.x][eu.y] = true;
f[eu.x][eu.y] = f[e.x][e.y] + cd[e.x][e.y];
if(!inque[eu.x][eu.y]){
que.push(eu);
inque[eu.x][eu.y]= true;
}
}
}
}
return f[][];
} inline void init(){
readInteger(n);
readInteger(sx);
readInteger(sy);
for(int i = , a, b; i <= n; i++){
readInteger(a);
readInteger(b);
cd[a][b] = ;
smax(bx, a);
smax(by, b);
}
bx++, by++;
} inline void solve(){
int result = spfa();
printf("%d", result);
} int main(){
freopen("tractor.in", "r", stdin);
freopen("tractor.out", "w", stdout);
init();
solve();
return ;
}
题目描述
Farmer John is building a nicely-landscaped garden, and needs to move alarge amount of dirt in the process.The garden consists of a sequence of N flowerbeds (1 <= N <= 100), whereflowerbed i initially contains A_i units of dirt. Farmer John would liketo re-landscape the garden so that each flowerbed i instead contains B_iunits of dirt. The A_i's and B_i's are all integers in the range 0..10.To landscape the garden, Farmer John has several options: he can purchaseone unit of dirt and place it in a flowerbed of his choice for $X. He can remove one unit of dirt from a flowerbed of his choice and have it shippedaway for $Y. He can also transport one unit of dirt from flowerbed i toflowerbed j at a cost of $Z times |i-j|. Please compute the minimum totalcost for Farmer John to complete his landscaping project.
输入
第1行:4个整数 N, X, Y, Z (0 <= X, Y, Z <= 1000).
第2..1+N行: 每行2个整数 A_i 和 B_i.
输出
第1行:1个整数,表示最小的花费。
样例输入
样例输出
提示
INPUT DETAILS: There are 4 flowerbeds in a row, initially with 1, 2, 3, and 4 units of dirt. Farmer John wishes to transform them so they have 4, 3, 2, and 0 units of dirt, respectively. The costs for adding, removing, and transporting dirt are 100, 200, and 1.
OUTPUT DETAILS: One unit of dirt must be removed (from flowerbed #4), at a cost of 200. The remaining dirt can be moved at a cost of 10 (3 units from flowerbed #4 to flowerbed #1, 1 unit from flowerbed #3 to flowerbed #2).
讲一下题意:
大概就这样子,方法是dp
把A序列和B序列拆成不同的状态,不好直接说,假设A序列是:1 0
就拆成这么几个状态
B序列是2 2
f[i][j]表示A序列的第i个状态到B序列第j个状态最小的代价
前两种方式可以用如下方式来转移
f[i][j] = min(f[i - 1][j] + y, f[i][j - 1] + x);
(对照着上面两个表看看很容易就能明白,虽然有点绕)
还要考虑记一个位置(看代码),不然无法处理第三种操作
第三种操作相当于将两个已知的位置,一个加1,一个减1,
f[i][j] = min(f[i][j], f[i - 1][j - 1] + z * (a[i] - b[j]));
详情可以参考:http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Dynamic/Edit/
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef bool boolean;
#define inf 0xfffffff
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != -);
if(x == -){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} int n;
int x, y, z;
int f[][];
int *a, *b; //第i个状态所处位置
int ca, cb; //原序列和目标序列的状态数 int main(){
freopen("landscaping.in", "r", stdin);
freopen("landscaping.out", "w", stdout);
readInteger(n);
readInteger(x);
readInteger(y);
readInteger(z); a = new int[(const int)(n * + )];
b = new int[(const int)(n * + )]; ca = cb = ;
for(int i = , j; i <= n; i++){
readInteger(j);
while(j > ) a[ca++] = i, j--;
readInteger(j);
while(j > ) b[cb++] = i, j--;
} for(int i = ; i < ca; i++) f[i][] = i * y;
for(int i = ; i < cb; i++) f[][i] = i * x; for(int i = ; i < ca; i++){
for(int j = ; j < cb; j++){
f[i][j] = inf;
smin(f[i][j], f[i - ][j] + y);
smin(f[i][j], f[i][j - ] + x);
smin(f[i][j], f[i - ][j - ] + z * abs(a[i] - b[j]));
}
} printf("%d", f[ca - ][cb - ]);
return ;
}
描述
明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
这个选择题中的每个表达式都满足下面的性质:
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……
对于30%的数据,表达式中只可能出现两种运算符‘+’和‘-’;
对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。
格式
输入格式
输入的第一行给出的是题干中的表达式。第二行是一个整数n(2 <= n <= 26),表示选项的个数。后面n行,每行包括一个选项中的表达式。这n个选项的标号分别是A,B,C,D……
输入中的表达式的长度都不超过50个字符,而且保证选项中总有表达式和题干中的表达式是等价的。
输出格式
输出包括一行,这一行包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。
样例输入
( a + ) ^ (a-)^+*a
a + + a
a^ + * a * + ^ + - +a -a
样例输出
AC
限制
1s
来源
NOIP2005 第四题
(ps:由于pdf写得太水,所以直接复制vj的:https://vijos.org/p/1003)
正解是将a随便带一个值进去算,mod几个质数,全部都相等才判定为相等
当然我们同学有写200多行多项式乘法AC的(十分膜拜)
我嘛,鉴于整型自带溢出,而且10个点,重复的可能性很小,就把a = -10001带进去算,轻松AC
Code(以前的代码)
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
typedef bool boolean;
stack<char> op;
stack<long long> num;
int n;
boolean can(char oper){
if(op.empty()) return false;
if(oper=='(') return false;
if(oper==')') return true;
char cf=op.top();
if(cf=='(') return false;
if(cf==oper) return true;
if(cf==')') return true;
if(cf=='^'&&oper!=')') return true;
if(cf=='*'&&(oper=='+'||oper=='-')) return true;
if(cf=='+'&&oper=='-') return true;
if(cf=='-'&&oper=='+') return true;
return false;
}
long long pow(long long n,short int pos){
if(pos==) return n;
if(pos%==) return pow(n,pos/)*pow(n,pos/)*n;
return pow(n,pos/)*pow(n,pos/);
}
long long cale(char oper){
long long result = ;
long long b = num.top();
num.pop();
long long a = num.top();
num.pop();
switch(oper){
case '+':
result=a+b;
break;
case '-':
result=a-b;
break;
case '*':
result=a*b;
break;
case '^':
result=pow(a,b);
break;
}
op.pop();
return result;
}
long long getResult(string str){
int index=;
while(index<str.length()){
if(str[index]==' '){
index++;
continue;
}
if(index<str.length()&&str[index]>=''&&str[index]<=''){
int math = ;
while(index<str.length()&&str[index]>=''&&str[index]<=''){
math*=;
math+=str[index]-'';
index++;
}
num.push(math);
continue;
}
if(index<str.length()&&str[index]=='a'){
num.push(-);
index++;
continue;
}
while(index<str.length()&&(!op.empty())&&can(str[index])){
if(str[index]==')'){
while(op.top()!='(')
num.push(cale(op.top()));
op.pop();
break;
}else{
num.push(cale(op.top()));
}
}
if(str[index]!=')')
op.push(str[index]);
index++;
}
while(!op.empty()){
num.push(cale(op.top()));
}
long long result=num.top();
num.pop();
return result;
}
string s;
long long answer;
int main(){
getline(cin,s);
answer=getResult(s);
cin>>n;
getline(cin,s);
for(int i=;i<=n;i++){
getline(cin,s);
if(getResult(s)==answer) cout<<(char)('A'+i-);
}
return ;
}
[题解]某模拟题(USACO月赛部分题+noip2005部分题)的更多相关文章
- 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)
虚拟化构建二分图 ------BZOJ2080 题解+浅谈几道双栈排序思想的题 本题的题解在最下面↓↓↓ 不得不说,第一次接触类似于双栈排序的这种题,是在BZOJ的五月月赛上. [BZOJ4881][ ...
- 洛谷 P3695 CYaRon!语 题解 【模拟】【字符串】
大模拟好啊! 万一远古计算机让我写个解释器还真是得爆零了呢. 题目背景 「千歌です」(我是千歌).「曜です」(我是曜).「ルビィです」(我是露比).「3人合わせて.We are CYaRon! よろし ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- USACO月赛数据
终于找到了usaco月赛的数据…… 根据月赛的名称,我们可以写出数据地址.比如08年一月的月赛即是:http://contest.usaco.org/JAN08 这里要注意区分大小写.
- 《ACM国际大学生程序设计竞赛题解Ⅰ》——模拟题
这篇文章来介绍一些模拟题,即一类按照题目要求将现实的操作转换成程序语言. zoj1003: On every June 1st, the Children's Day, there will be a ...
- 某模拟题(USACO部分题+noip2005部分题)
题目描述 农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上.FJ有一辆拖拉机,也在农场上.拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内.拖拉 ...
- 洛谷3月月赛div2 题解(模拟+数学+贪心+数学)
由于本人太蒻了,div1的没有参加,胡乱写了写div2的代码就赶过来了. T1 苏联人 题目背景 题目名称是吸引你点进来的. 这是一道正常的题,和苏联没有任何关系. 题目描述 你在打 EE Round ...
- NOIP模拟测试39,思维禁锢专场「工业题·玄学题·卡常题」
工业题 题解 抱歉,题解没时间写了 代码 #include<bits/stdc++.h> using namespace std; #define ll long long #define ...
- Noip模拟13 2021.7.13:再刚题,就剁手&&生日祭
T1 工业题 这波行列看反就非常尴尬.....口糊出所有正解想到的唯独行列看反全盘炸列(因为和T1斗智斗勇两个半小时...) 这题就是肯定是个O(n+m)的,那就往哪里想,a,b和前面的系数分开求,前 ...
随机推荐
- lua遍历文件夹, zerobrane下载
参考的这个http://www.cnblogs.com/jiufangding/p/3931585.html,配合批处理. zerobrane下载(上一篇博客忘掉了): http://files.cn ...
- Yii2 AR find用法 (2016-05-18 12:06:01)
Yii2 AR find用法 (2016-05-18 12:06:01) 转载▼ User::find()->all(); 返回所有数据 User::findOne($id); ...
- MSSQL 和 REDIS的数据类型对应关系
when user_type_id in (34) then 'BLOB' --image when user_type_id in (35) then 'CLOB' --tex ...
- Durid(一): 原理架构
Durid是在2013年底开源出来的,当前最新版本0.9.2, 主要解决的是对实时数据以及较近时间的历史数据的多维查询提供高并发(多用户),低延时,高可靠性的问题.对比Druid与其他解决方案,Kyl ...
- zookeeper安装及部署
安装及部署 一. 单机安装.配置 1.下载zookeeper二进制安装包 下载 curl -L -O http://apache.fayea.com/zookeeper/stable/zookeepe ...
- Mysql 自定义HASH索引带来的巨大性能提升----[真相篇]
推倒重来 俗话说no zuo no die why you try,这时候我又忍不住zuo了,吭哧吭哧的把解决过程发上博客,向全世界宣布,哥又搞定个难题. 剧情的发展往往是看起来主角完全掌握了局势的情 ...
- sql rollup解决责任人收支余额
问题的提出是周聪之前问过我的项目往来查询,不好在NC上一次性查询到.然后我就搞了一个很长的项目对账,发布了NC的节点. 现在我做了总二的总账,每次领导问我项目还有多少钱,收了多少付了多少,我还要通过科 ...
- Oracle导入和导出
导出:EXP userid=<username>/<password>@<service_name> file=<dmpname> e.g.exp sa ...
- [Tex学习笔记]写文章需要规范、需要引用到位. [LaTeX代码]
\documentclass{ctexart} \usepackage{CJK,amsmath,amssymb,amsthm} \begin{document} 写文章需要规范.需要引用到位. 方程: ...
- Linux 下没有conio.h 已解决
原文:http://blog.sina.com.cn/s/blog_6a95e00b0100zqvf.html #include <stdio.h>//#include <conio ...