10.13 noip模拟试题
Porble 1时间与空间之旅(tstrip.*)
题目描述
公元22××年,宇宙中最普遍的交通工具是spaceship。spaceship的出现使得星系之间的联系变得更为紧密,所以spaceship船长也成了最热门的职业之一。当然,要成为一名出色的船长,必须通过严格的考核,例如下面是最简单的问题中的一个。
用1~n的整数给n个星系标号,目前你在标号为1的星系,你需要送快递到标号为n的星系,星系之间由于存在陨石带,并不是都可以直连的。同时,由于超时空隧道的存在,在某些星系间飞行会出现时间静止甚至倒流,飞行时间为0或为负数。另外,由星系i到星系j的时间和由星系j到星系i的时间不一定是相同的。
在寄出日期之前收到快递被认为是不允许的,所以每部spaceship上都有一个速度调节装置,可以调节飞行的时间。简单来说其功能就是让所有两个星系间的飞行时间(如果可以直达)都增加或减少相同的整数值,你的任务就是调整速度调节器,找出一条用最短时间完成任务的路径,并且保证这个最短时间的值大于或等于0。
输入格式
输入文件包含多组数据,第1个数为T,表示数据的数量。
对于每一组数据,输入第1行为两个正整数N(2≤N≤100),E(1≤E≤N*(N-1)/2),为星系的个数和星系间飞行的路线数。然后E行,每行三个整数i,j和t(1≤i,j≤N,i≠j,-100000≤t≤100000),表示由星系i到星系j飞行的时间为t。由i到j最多只会有一条飞行线路。
输出格式
输出文件共T行,每组数据输出一行;
如果可以通过调节速度调节器完成任务,则输出一个非负整数,表示由星系1到星系N的最短时间。
如果不能由星系1到达星系N,则输出-1。
输入样例
1
4 5
1 2 1
1 3 1
2 3 -3
3 1 1
3 4 1
输出样例
2
样例说明
输入样例如图所示,其中节点标号表示相应星系,节点间数字表示所需时间。
如果设置速度控制器的值为0,则有如下路径:1→2→3→1→2→……→3→4,使得投递的时间为负无穷大,显然是不符合要求的,所以应该把速度控制器的值设为1,相当于每个时间值加1,得到的最短路径为1→2→3→4,所需时间为2+(-2)+2=2。
/*
唯一一个会做的题还被卡了
多组数据啊....
考虑的不全面 没造数据 也没拍.....
有种情况就是 如果负环不在1-n的最短路上 要把它忽略.
先把到不了n的删掉再来二分.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 10010
#define inf 100000
using namespace std;
int T,n,m,num,head[],c[],dis[],f[],ans;
int Head[],Num,Ca[];
queue<int>q;
struct node{
int v,t,pre;
}e[maxn],E[maxn];
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Clear(){
num=Num=;ans=-inf-;
memset(Ca,,sizeof(Ca));
memset(head,,sizeof(head));
memset(Head,,sizeof(Head));
}
void add(int from,int to,int dis){
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void Add(int from,int to,int dis){
Num++;E[Num].v=to;
E[Num].t=dis;
E[Num].pre=Head[from];
Head[from]=Num;
}
void Dfs(int x){
Ca[x]=;
for(int i=Head[x];i;i=E[i].pre)
if(Ca[E[i].v]==)Dfs(E[i].v);
}
bool Judge(int x){
while(!q.empty())q.pop();
memset(f,,sizeof(f));
memset(c,,sizeof(c));
memset(dis,/,sizeof(dis));
dis[]=;f[]=;
q.push();c[]++;
while(!q.empty()){
int k=q.front();
q.pop();f[k]=;
if(c[k]>n)return ;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(Ca[v]==)continue;
if(dis[v]>dis[k]+e[i].t+x){
dis[v]=dis[k]+e[i].t+x;
if(f[v]==){
c[v]++;f[v]=;q.push(v);
}
}
}
}
if(dis[n]<||dis[n]==dis[])return ;
else return ;
}
int main()
{
freopen("tstrip.in","r",stdin);
freopen("tstrip.out","w",stdout);
T=init();
while(T--){
n=init();m=init();
Clear();int u,v,t;
for(int i=;i<=m;i++){
u=init();v=init();t=init();
add(u,v,t);Add(v,u,t);
}
Dfs(n);
int l=-inf,r=inf;
while(l<=r){
int mid=(l+r)/;
if(Judge(mid)){
r=mid-;ans=(ans,dis[n]);
}
else l=mid+;
}
if(ans==-inf-)printf("-1\n");
else printf("%d\n",ans);
}
}
Problem 2 狐狸的谜语(puzzle.*)
题目描述
话说某一个月黑风高的晚上,一只褐色的狐狸快速地跳过了一只懒狗,并留下一个字符串“032089”和一个数字5。
这其中一定隐含了某些秘密!酷爱思考的你马上发现,这个字符串可以写成:“03+2+0*89”,结果为5。这是一个非常有趣的问题!
现在给出一个长度为N的数字字符串和一个数字T,要求插入最少的加号或者乘号,使得数字字符串的运算结果为T。运算符*号优先级高于+号,运算数可以有任意个前导0。
榆入格式
输入不超过5组数据,每组数据两行。
每组数据的第1行为长度为N,只包含0~9的数字字符串,第2行为一个数字T。
输入T<0表示输入结束。
输出格式
输出一个数字单独占一行,表示最少需要添加的运算符(+号或*号)数,无解输出-1。
输入样例
032089
5
333
9
00
-1
输出样例
3
2
数据范围
对于30%的数据,有1≤N≤10,0≤T≤50。
对于50%的数据,有1≤N≤15,0≤T≤200。
对于全部的数据,有1≤N≤20,0≤T≤200。
/*
普通的迭代 30分
又是多组数据...
枚举加sum个符号
暴力搞出放在哪
最后 算值
还写了个表达式求值
显然有点浪费..
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int T,c[],ans,falg,len,sum;
char s[];
bool Judge(){
int l=,s1=,s2=,p=;
ll x,y,A[]={};
char a[]={},B[]={};
for(int i=;i<len;i++){
a[l++]=s[i];
if(c[i]==)a[l++]='+';
if(c[i]==)a[l++]='*';
}
while(p<l){
if(a[p]<''||a[p]>''){
if(a[p]=='*')B[++s2]='*';
else{
while(s2&&s1>=){
x=A[s1];y=A[s1-];
if(B[s2]=='+')x+=y;
else x*=y;
s2--;s1--;A[s1]=x;
}
B[++s2]='+';
}
p++;
}
else{
x=;
while(a[p]>=''&&a[p]<=''){
x=x*+a[p]-'';p++;
}
A[++s1]=x;
}
}
while(s2&&s1>=){
x=A[s1];y=A[s1-];
if(B[s2]=='+')x+=y;
else x*=y;
s2--;s1--;A[s1]=x;
}
return A[]==T;
}
void Dfs(int now,int num){
if(now==len-||num==sum){
if(Judge())falg=;
return;
}
c[now]=;Dfs(now+,num+);
c[now]=;if(falg)return;
c[now]=;Dfs(now+,num+);
c[now]=;if(falg)return;
Dfs(now+,num);if(falg)return;
}
int main()
{
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
while(){
ans=;falg=;
scanf("%s%d",s,&T);
if(T<)break;
len=strlen(s);
for(int i=;i<len;i++){
sum=i;Dfs(,);
if(falg){
ans=i;break;
}
}
if(ans==)printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
/*
正解不是放到最后一块算
而是边添边算 至于优先级问题
维护最后几个数的乘积和这之前的值就好了
这样能剪枝了!
因为给定T是有范围的 +*只会使值变大(除了后面*0)
然后大了就剪掉 注意处理一下保证后面没有零
这个写迭代居然T一个点
改成二分就好了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int T,c[],ans,falg,len,sum,r[][],a[];
char s[];
void Solve(){
for(int i=;i<=len;i++)
for(int j=i;j<=len;j++){
r[i][j]=r[i][j-]*+s[j]-'';
if(r[i][j]>T+)r[i][j]=T+;
}
for(int i=;i<=len;i++){
int flag=;
for(int j=i;j<=len;j++)
if(s[j]==''){
flag=;break;
}
if(!flag)a[i]=;
}
}
void Dfs(int now,int num,int s,int c,int pre){
if(s>T||num>sum)return;
if(now==len){
if(s+c*r[pre+][now]==T)falg=;
return;
}
if(a[now-]&&s+c>T)return;
Dfs(now+,num+,s,c*r[pre+][now],now);// *
Dfs(now+,num+,s+c*r[pre+][now],,now);// +
Dfs(now+,num,s,c,pre);// kong
}
int main()
{
//freopen("puzzle.in","r",stdin);
//freopen("puzzle.out","w",stdout);
while(){
ans=;falg=;
memset(r,,sizeof(r));
memset(a,,sizeof(a));
scanf("%s%d",s+,&T);
if(T<)break;
len=strlen(s+);
Solve();
int l=,r=len-;
while(l<=r){
falg=;
sum=(l+r)/;
Dfs(,,,,);
if(falg){
r=sum-;
ans=sum;
}
else l=sum+;
}
if(ans==)printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
Problem 3花园的守护之神(greendam.*)
题目描述
看着正在被上古神兽们摧残的花园,花园的守护之神――小Bug同学泪流满面。然而,FZOI不相信眼泪,小bug与神兽们的战争将进行到底!
通过google,小Bug得知,神兽们来自遥远的戈壁。为了扭转战局,小Bug决定拖延神兽增援的速度。从戈壁到达花园的路径错综复杂,由若干段双向的小路组成。神兽们通过每段小路都需要一段时间。小Bug可以通过向其中的一些小路投掷小xie来拖延神兽。她可以向任意小路投掷小Xie,而且可以在同一段小路上投掷多只小xie。每只小Xie可以拖延神兽一个单位的时间。即神兽通过整段路程的总时间等于没有小xie时他们通过同样路径的时间加上路上经过的所有小路上的小xie数目总和。
神兽们是很聪明的。他们会在出发前侦查到每一段小路上的小Xie数目,然后选择总时间最短的路径。小Bug现在很想知道最少需要多少只小Xie,才能使得神兽从戈壁来到花园的时间变长。作为花园中可爱的花朵,你能帮助她吗?
输入格式
第1行包括一个整数N,表示地图中路点的个数;一个整数M,表示小路个数;以及整数S和T,分别表示戈壁和花园的路点编号。N个路点分别被编号为自然数1~N。
以下M行,每行三个整数A、B和C,表示路点A和B之间有一条小路相连,且通过它需要的时间为C。
输入数据保证两路点间最多只有一条小路相连,且戈壁和花园的路点是连通的。
输出格式
一个整数,表示使S到T之间最短路增长所需要的最少的小xie的数目。
输入样例
5 5 1 5
1 2 1
2 3 3
1 4 2
4 3 2
5 1 2
输出样例
1
数据范围
对于30%的数据,满足N≤10,M≤50。
对于50%的数据,满足N≤200,M≤10000。
对于全部的数据,满足N≤1000,M≤499500,0<C≤1000000。
/*暴力30 正解网络流 不会....*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 1010
using namespace std;
int n,m,num,head[maxn],S,T,dis[maxn],f[maxn],mx,sum,falg;
struct node{
int v,t,pre,x;
}e[maxn*maxn];
queue<int>q;
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Add(int from,int to,int dis){
e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num++;
}
int SPFA(){
while(!q.empty())q.pop();
memset(f,,sizeof(f));
memset(dis,/,sizeof(dis));
dis[S]=;f[S]=;
q.push(S);
while(!q.empty()){
int k=q.front();
q.pop();f[k]=;
for(int i=head[k];i!=-;i=e[i].pre){
int v=e[i].v;
if(dis[v]>dis[k]+e[i].t+e[i].x){
dis[v]=dis[k]+e[i].t+e[i].x;
if(f[v]==){
f[v]=;q.push(v);
}
}
}
}
return dis[T];
}
void Dfs(int now,int s){
if(s==sum||now==num){
if(SPFA()>mx)falg=;
return;
}
e[now].x++;e[now^].x++;
Dfs(now+,s+);if(falg)return;
e[now].x--;e[now^].x--;
Dfs(now+,s);if(falg)return;
}
int main()
{
freopen("greendam.in","r",stdin);
freopen("greendam.out","w",stdout);
n=init();m=init();S=init();T=init();
int u,v,t;memset(head,-,sizeof(head));
for(int i=;i<=m;i++){
u=init();v=init();t=init();
Add(u,v,t);Add(v,u,t);
}
mx=SPFA();
for(sum=;sum<=m;sum++){
Dfs(,);
if(falg)break;
}
printf("%d\n",sum);
return ;
}
10.13 noip模拟试题的更多相关文章
- 10.26 noip模拟试题
enc[问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母.例如考虑映射规则:a->b, b- ...
- 10.4 noip模拟试题
题目名称 PA 青春 三部曲 名称 huakai taritari truetears 输入 huakai.in taritari.in truetears.in 输出 huakai.out tari ...
- 10.3 noip模拟试题
希望[题目描述]网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,“前进栈”.“后退栈”.这里你需要实现以下几个功能:BACK: 如果“后退栈”为空则忽略此命令. 否则将当前两面压入“ ...
- 11.13 noip模拟试题
题目名称 笔记 括号 城堡可执行文件名 note brackets castle输入文件名 note.in brackets.in castle.in输出文件名 note.in brackets.ou ...
- 10.27 noip模拟试题
1.铺瓷砖(tile.cpp/c/pas)[问题描述]有一面很长很长的墙. 你需要在这面墙上贴上两行瓷砖. 你的手头有两种不同尺寸的瓷砖,你希望用这两种瓷砖各贴一行.瓷砖的长可以用分数表示,贴在第一行 ...
- 10.24 noip模拟试题
尼玛pdf依旧不会粘23333 /* 每段合并到总的里面 假设总的有X个 这一段有Y个 一共有X+1个空 那么就有 C(X+1,1)+C(X+1,2)+C(X+1,3)+...+C(X+1,Y) 这样 ...
- 10.18 noip模拟试题
分火腿 (hdogs.pas/.c/.cpp) 时间限制:1s:内存限制 64MB 题目描述: 小月言要过四岁生日了,她的妈妈为她准备了n根火腿,她想将这些火腿均分给m位小朋友,所以她可能需要切火腿. ...
- 10.11 noip模拟试题
4题均为128M,1s 1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行, ...
- 10.8 noip模拟试题
1.花 (flower.cpp/c/pas) [问题描述] 商店里出售n种不同品种的花.为了装饰桌面,你打算买m支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买1支.求总共有几种不同的 ...
随机推荐
- 手动删除文件夹exe病毒并恢复原来文件夹
转自手动删除文件夹exe病毒并恢复原来文件夹 经常使用U盘.MP3.MP4等移动硬盘的大家,有时是不是会发现,移动硬盘里有现了exe文件,原来本来有一个文件夹的名字是 音乐 ,但后来发现 音乐 这个文 ...
- Girls' research
hdu3294:http://acm.hdu.edu.cn/showproblem.php?pid=3294 题意:就是给你一个串,然后求一个最长的回文串,输出起点及串,但是这里在之前要转化一下. 题 ...
- 【Windows 8】pid为4的system进程占用80端口的解决办法
因为Apache无法启动的原因,用netstat命令查看了一下80端口是否被占用了,如下: C:\Users\Maple>netstat -ano | findstr TCP LISTENING ...
- FLASH 存储学习-串行SPI NOR FLASH
1.1 SST25VF080B简介1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. l 容量:8MBit: l 最高SPI时钟频率:50MHz: l 低功耗模式下电流消耗:5uA ...
- Android开源项目发现--- 工具类快速开发篇(持续更新)
1. Guava Google的基于java1.6的类库集合的扩展项目 包括collections, caching, primitives support, concurrency librarie ...
- android工程混淆和反编译
一.工程文件的混淆 混淆文件下载:http://download.csdn.net/detail/lxq_xsyu/6328751 1.在根目录下添加progard.cfg文件 2.打开project ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- [LeetCode#253] Meeting Rooms II
Problem: Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2] ...
- 一起啃PRML - Preface 前言
一起啃PRML - 前言 Preface @copyright 转载请注明出处 http://www.cnblogs.com/chxer/ PRML,Pattern Recognition and M ...
- Light OJ 1037 - Agent 47(预处理状态压缩DP)
题目大意: 有个特工要执行任务,他会遭遇到最多15个目标,特工必须把他们全部杀死.当他杀死一个目标后他可以使用目标的武器来杀死其他人.因此他必须有一个杀人的顺序,使得他开枪的次数最小. 现在给你一个表 ...