NOIP模拟赛

by thmyl

 

题目名称

superman

market

Lemon_Soda

可执行文件名

superman

market

Lemon_Soda

输入文件

superman.in

market.in

Lemon_Soda.in

输出文件

superman.out

market.out

Lemon_Soda.out

时间限制

1s

1s

1s

是否有部分分

满分

100

100

100

空间限制

250M

128M

128M

测试点数量

5

10

10

Problem 1. superman

【题目描述】

小可乐是要登上世界顶峰的男人!为了向他的妹子证明自己的能力,他决定去撒哈拉沙漠找到依米花送给他的妹子。

假设途中经过N个地区,编号为1~N,小可乐一开始在编号为1的地区,编号为N的地区代表撒哈拉沙漠,地区之间由于地形差别悬殊,并不是都可以直连的。同时由于不同经度存在时差,小可乐看了当地的地方时会以为出现了时间静止甚至倒流,所以我们假设两地区之间的穿行时间可以是负数或0,另外,由地区i到地区j的时间和由地区j到地区i的时间不一定是相同的。

小可乐在非洲的网友DDL被他感动了,决定去城市n迎接小可乐的到来,小可乐可以自己调整行动速度,为了不让DDL等得太着急,他想调整自己行动的速度,使得在每一条路上花费的时间都加或减一个整数,你的任务是调整小可乐的行动速度,找出一条用最短时间到达地区N的路径,并且保证这个最短时间的值大于或等于0。

【输入格式】

输入文件包含多组数据,第1个数为T,表示数据的数量。

对于每一组数据,输入第1行为两个正整数N,E,为地区的个数和地区间的路线数。然后E行,每行三个整数i,j和t(1≤i,j≤N,i≠j),表示由地区i到地区j穿行的时间为t。由i到j最多只会有一条穿行线路。

【输出格式】

输出文件共T行,每组数据输出一行;

如果可以通过调节速度到达地区N,则输出一个非负整数,表示由地区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。

/*
因为与n不连通的负环对答案无影响
所以先floyd预处理连通性
二分每条边上增加的数量,然后spfa判断
判断的时候必须edge[i].to能连到n才可以进队列
入队列n次说明有负环,当前答案不可行。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> #define N 101 using namespace std;
int head[N],vis[N],d[N],p[N];
int can[N][N];
int n,m,ans,cnt,num;
queue<int>q;
struct node
{
int u,v,net,dis;
}e[N<<]; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void init()
{
memset(head,,sizeof head);
memset(p,,sizeof p);
memset(vis,,sizeof vis);
memset(can,,sizeof can);
for(int i=;i<=n;i++)
can[i][i]=;
cnt=;while(!q.empty()) q.pop();
} inline void add(int u,int v,int dis)
{
e[++cnt].v=v;e[cnt].net=head[u];e[cnt].dis=dis;head[u]=cnt;
} void dfs(int now)
{
vis[now]=;
for(int i=head[now];i;i=e[i].net)
{
int v=e[i].v;
if(vis[v])continue;
vis[v]=; dfs(v);
}return;
} void floyd()
{
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(can[i][k] && can[k][j]) can[i][j]=;
} bool spfa(int now)
{
memset(d,,sizeof d);
memset(vis,,sizeof vis);
memset(p,,sizeof p);
d[now]=;vis[now]=;q.push(now);
while(!q.empty())
{
int u=q.front();q.pop();vis[u]=;
for(int i=head[u];i;i=e[i].net)
{
int v=e[i].v;
if(d[v]>d[u]+e[i].dis && can[v][n])
{
d[v]=d[u]+e[i].dis;
if(!vis[v])
{
vis[v]=;
q.push(v);
if(++p[v]>n) return false;
}
}
}
}
if(d[n]<) return false;
return true;
} bool AD(int k)
{
for(int i=;i<=m;i++) e[i].dis+=k;
bool res=spfa();
for(int i=;i<=m;i++) e[i].dis-=k;
return res;
} int main()
{
int x,y,T,z;
T=read();
while(T--)
{
n=read();m=read();init();
for(int i=;i<=m;i++)
{
x=read();y=read();z=read();
can[x][y]=;
add(x,y,z);
}
dfs();
if(!vis[n]) printf("-1\n");
else
{
floyd();
int l=-,r=;
while(l<=r)
{
int mid=(l+r)>>;
if(AD(mid)) r=mid-,ans=mid;
else l=mid+;
}AD(ans);
printf("%d\n",d[n]);
}
}
return ;
}

Problem 2. market

【题目描述】

小可乐的妹子不在家,他只好自己去逛超市,小可乐最喜欢喝汽水,买到汽水会使小可乐开心起来,但是他也不愿意看到手里的毛毛变少,所以每买一瓶汽水也会有点难过,很显然他又遇到了很多麻烦。

现在小可乐面前有n瓶汽水,编号分别为1,2,3,……,n。他可以在这当中任意选择任意多瓶。其中第i瓶汽水有两个属性Wi和Ri,当他选择了第i瓶汽水后,就可以获得Wi的开心值;但是,他选择该汽水以后选择的所有汽水的开心值都会减少Ri。现在请你求出,该选择哪些汽水,并且该以什么样的顺序选取这些汽水,才能使得小可乐获得的开心值最大。

注意,开心值的减少是会叠加的。比如,选择了第i瓶汽水,那么就会获得Wi的开心值;然后又选择第j瓶汽水,又会获得了Wj-Ri开心值;之后又选择第k瓶汽水,又会获得Wk-Ri-Rj的开心值;那么他获得的开心值总和为Wi+(Wj-Ri)+(Wk-Ri-Rj)。

【输入格式】

第一行一个正整数n,表示汽水的瓶数。

接下来第2行到第n+1行,每行两个正整数Wi和Ri,含义如题目所述。

【输出格式】

输出仅一行,表示最大的开心值。

【输入样例】

2

5 2

3 5

【输出样例】

6

【说明】

20%的数据满足:n<=5,0<=Wi,Ri<=1000。

50%的数据满足:n<=15,0<=Wi,Ri<=1000。

100%的数据满足:n<=3000,0<=Wi,Ri<=200000。

样例解释:我们可以选择第1瓶汽水,获得了5点开心值;之后我们再选择第2瓶汽水,获得3-2=1点开心值。最后总的开心值为5+1=6。

/*
首先仍然是要按照Ri从大到小排个序。然后设F[i][j]表示前i个物品中选j个可以获得的收益最大值。
状态转移方程:F[i][j]=max{F[i-1][j],F[i-1][j-1]+W[i]-R[i]*(j-1)}
边界条件:F[1][1]=W[1]
最后的答案=max{F[n][i]}
*/
#include<iostream>
#include<cstdio>
#include<algorithm> #define N 3010 using namespace std; int ans,n,dp[N][N];
struct node
{
int w,r;
}a[N]; int cmp(node x,node y){return x.r>y.r;} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d%d",&a[i].w,&a[i].r);
sort(a+,a+n+,cmp); dp[][]=a[].w;
for(int i=;i<=n;i++)
for(int j=;j<=i;j++)
dp[i][j]=max(dp[i][j],max(dp[i-][j],dp[i-][j-]+a[i].w-a[i].r*(j-)));
for(int i=;i<=n;i++) ans=max(ans,dp[n][i]);
printf("%d",ans);
fclose(stdin);fclose(stdout);
return ;
}

Problem 3. Lemon_Soda

【题目描述】

小可乐惊喜的发现一瓶汽水中了再来一瓶,他去商店换汽水的时候,店主Lemon和Soda打算耍耍他,出了一个难题,而且做不出来就不给汽水喝

这题说的是:

使得  达到或超过 n 位数字的最小正整数 x 是多少?

小可乐见了两位妹子紧张的不敢说话,快请你帮帮他解决这个难题吧

【输入格式】

一个正整数 n

【输出格式】

使得  达到 n 位数字的最小正整数 x

【输入样例】

11

【输出样例】

10

【说明】

n<=2000000000

换底公式

/*
看到如此之大的数据范围,显然强行计算x^x的位数是不现实的,不仅需要高精度,而且效率极低。
题目的核心在于如何计算x^x的位数,可以利用对数的方法,log10(x)就是x的位数。
也就是 log10(x^x)>=n-1
如此判定方法就是简单了,代码形式就是 x * log(x) / log(10)(换底公式) >= n - 1
求最小,很明显是二分搜索,二分套一个判断函数就完成了此题。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath> #define N 1000000000 using namespace std; bool judge(long long x, int n)
{
return x*(log(x)/log())>=n-;
} void BC(int l, int r, int n)
{
int ans;
while(l<=r)
{
int mid=(l + r)>>;
bool cur=judge(1ll*mid,n);
if(cur)r=mid-,ans=mid;
else l=mid+;
}
printf("%d\n",ans);
return;
} int main()
{
int n;
scanf("%d", &n);
BC(,N,n);
return ;
}

9.11NOIP模拟题的更多相关文章

  1. 10.11NOIP模拟题(3)

    /* 可以看出,对于一段区间[L,R]如果统计了答案 若a[L]<a[R],那么当右端点往左移时答案不会更优,a[R]>a[L]同理 所以两个指针分别从头尾往中间扫那边小移哪边即可. */ ...

  2. 10.11NOIP模拟题(2)

    /* string水过 */ #include<bits/stdc++.h> #define N 1001 using namespace std; int n,x,y,m,pre; st ...

  3. poj 1008:Maya Calendar(模拟题,玛雅日历转换)

    Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 D ...

  4. poj 1888 Crossword Answers 模拟题

    Crossword Answers Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 869   Accepted: 405 D ...

  5. CodeForces - 427B (模拟题)

    Prison Transfer Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  6. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

  7. 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中

    题目名称 正确答案  序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer. ...

  8. UVALive 4222 Dance 模拟题

    Dance 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&pag ...

  9. cdoj 25 点球大战(penalty) 模拟题

    点球大战(penalty) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/2 ...

随机推荐

  1. 10JDBC、CURD、XML、XPath

    10JDBC.CURD.XML.XPath-2018/07/20 1.JDBC JDBC:java database connectivity JDBC与数据库驱动的关系:接口与实现的关系. JDBC ...

  2. C++/C union使用记一下锅

    //首先,学习编程一定要记得加几个群或者加几个讨论组,因为这样你才能不断地进步还有吵架/滑稽 记一下 关于使用union结构体时遇到的一些坑 To zero-initialize an object ...

  3. ubuntu 14.04 挂载window共享目录

    (1) 先在ubuntu系统里,新建一个目录用于挂载,目录假设为 /mnt/win: sudo mkdir /mnt/win (2)在windows系统,共享出一个文件夹,共享名称假设为www sud ...

  4. JSP内置对象说明

    JSP内置对象说明 制作人:全心全意 request对象:request对象封装了由客户端生成的HTTP请求的所有细节,主要包括HTTP头信息.系统信息.请求方式和请求参数等.通过request对象提 ...

  5. react入门----组件的基础用法

    1.组件 <!-- React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件.React.createClass 方法就用于生成一个组件类 ...

  6. springboot项目--传入参数校验-----SpringBoot开发详解(五)--Controller接收参数以及参数校验----https://blog.csdn.net/qq_31001665/article/details/71075743

    https://blog.csdn.net/qq_31001665/article/details/71075743 springboot项目--传入参数校验-----SpringBoot开发详解(五 ...

  7. Codeforces Round #249 (Div. 2) 总结

    D.E还是很难的.....C不想多说什么... A:提意:给出每一组人的个数,以及一次车载容量,求出最少需要多少次才能载走所有的人. water: http://codeforces.com/cont ...

  8. hdu 2647拓扑排序 结构体模拟容器

    #include<stdio.h> #include<queue> #include<iostream> using namespace std; #define ...

  9. vue组件知识总结

    vue组件化开发 将一个页面分割成若干个组件,一个页面js+css+html,将自己类容分割出来,方便开发,更好了维护我们的代码,每个组件封装自己的js+html+css,样式命名冲突 组件分类 页面 ...

  10. 【故障处理】初始化数据时报600错误kcbz_check_objd_typ_3

    http://blog.itpub.net/519536/viewspace-661905/