【SinGuLaRiTy-1030】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

对于所有题目: Time Limit: 1s | Memory Limit: 256MB

               

旅行 (travel)

题目描述

Mr_H 旗下的 n 个OIer 坐船外出旅行!
但是他们只有一艘船,虽然船能装下全部的Oier,但太拥挤将会影响众OIer 的心情,所以Mr_H决定选择一部分Oier 去。我们假设,每个人单独坐船的快乐程度是Ci,而船上每多一个人,他的快乐程度会减去Di。
现在你的任务是帮助Mr_H 计算,选择那些人,才能使船上所有人的快乐程度之和达到最大。

输入

第 1 行是一个整数n,表示OIer 的人数;
第 2 行有n 个整数,第i 个整数表示第i 个人人单独坐船的快乐程度Ci(1<=Ci<=10000);
第 3 行有n 个整数,第i 个整数表示每多1 人,第i 个人快乐程度的下降值Di(1<=Di<=10)。

输出

第 1 行一个整数,是最大的快乐程度之和;
第 2 行一个整数,是最大的快乐程度之和所对应的汽艇上的人数(若有多种方案,则输出人数最多的)。

样例数据

样例输入 样例输出

6
10 10 10 10 10 9
2 2 2 2 2 3

18
3

<数据范围>

对于30%的数据,n<=20;
对于100%的数据,n<=1000。

解析

很明显,直接枚举是没有必要的。我们可以枚举人数 K,然后算出在这种情况下每个人的快乐程度。然后贪心地取前K 大的数,这样就得到了 O(n^2*logn) 的算法。

Code

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath> #define MAXN 1010
#define INF 2000000000 using namespace std; int n,d[MAXN][MAXN];
int ans=-INF; void init()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&d[][i]);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
for(int j=;j<=n;j++)
d[j][i]=d[j-][i]-x;
}
} int main()
{
init();
int s;
for(int i=;i<=n;i++)
{
sort(d[i]+,d[i]++n);
if(d[i][n-i+]<=)
break;
int x=;
for(int j=;j<i;j++)
x+=d[i][n-j];
if(ans<=x)
{
ans=x;
s=i;
}
}
printf("%d\n%d",ans,s);
return ;
}

数据 (data)

题目描述

Mr_H 出了一道信息学竞赛题,就是给 n 个数排序。输入格式是这样的:
试题有若干组数据。每组数据的第一个是一个整数 n,表示总共有 n 个数待排序;接下来 n 个整数,分别表示这n 个待排序的数。
例如:3 4 2 –1 4 1 2 3 4,就表示有两组数据。第一组有3 个数(4,2,-1),第二组有4个数(1,2,3,4)。可是现在Mr_H 做的输入数据出了一些问题。例如:2 1 9 3 2 按理说第一组数据有2 个数(1,9),第二组数据有3 个数,可是“3”后面并没有出现三个数,只出现了一个数“2”而已!
现在 Mr_H 需要对数据进行修改,改动中“一步”的含义是对文件中的某一个数+1 或-1,写一个程序,计算最少需要多少步才能将数据改得合法。

输入

第一行一个整数m,表示Mr_H 做的输入数据包含的整数个数。第二行包含m 个整数a[i],每个整数的绝对值不超过10000。

输出

一个整数,表示把数据修改为合法的情况下,最少需要多少步。

样例数据

样例输入1 样例输出1

4
1 9 3 2

2
样例输入2 样例输出2

10
4 4 3 5 0 -4 -2 -1 3 5

3

<数据范围>

对于 20%的数据,m<=10, |a[i]|<=5;
对于60%的数据,m<=5000, |a[i]|<=10000
对于100%的数据,m<=100000, |a[i]|<=10000

解析

先来谈谈图论的解法,简单的说就是连边然后找最短路:若a[i]>0,那么就说明这个数可以用来表示数列的长度,我们就从a[i]连一条边到下一个数列i+a[i]+1,并设定其权值为0——因为这里实际上不需要耗费任何操作。如果i+a[i]+1超过了n怎么办呢?我们就在任意两个相邻的数间连一条权值为1的边——这里的左移右移就相当于加和减的操作,是需要消耗布数的。注意:第一个点和第二个点不能连,会出毒的。另外,若a[1]<0,我们显然要将其变为正数,于是这样的话我们需要在ans后面直接加上a[1],即使a[1]变为正数的步数。至于最后的答案嘛,直接跑1~n的最短路就行了。

不过,这么玄(zhèng) 学(cháng) 的东西怎么能是标准解法呢?要看DP+优化的同学还是直接 [下载PDF题解] 好了。

Code

#include<cstdio>
#include<queue>
#include<vector>
#include<iostream> #define need 110003
#define inf 1e9 using namespace std; int n,nn; inline void Read(int &d)
{
char t=getchar();bool mark=false;
while(t<''||t>'') {if(t=='-') mark=true;t=getchar();}
for(d=;!(t<''||t>'');t=getchar()) d=(d<<)+(d<<)+t-'';
if(mark) d=-d;
} struct bian
{
int la,en,len;
};
vector<bian> w; int tot,fi[need]; void add(const int &a,const int &b,const int &c)
{
tot++;
w.push_back((bian){fi[a],b,c});
fi[a]=tot;
} int s,e; struct fy
{
int dis,id;
bool operator< (const fy &b) const
{
return dis>b.dis;
}
};
priority_queue<fy> q; bool getans[need];
int dis[need]; void dijkstra(int s)
{
for(int i=;i<=nn;i++)
{
dis[i]=inf;
getans[i]=false;
}
q.push((fy){,s});
dis[s]=;
int x,y,t;
while(!q.empty())
{
while(!q.empty()&&getans[q.top().id])
q.pop();
x=q.top().id;
if(x==e)
return ;
getans[x]=true;
q.pop();
for(t=fi[x];t;t=w[t].la)
{
y=w[t].en;
if(getans[y])
continue;
if(dis[y]>dis[x]+w[t].len)
{
dis[y]=dis[x]+w[t].len;
q.push((fy){dis[y],y});
}
}
}
} int main()
{
w.resize();
int n;
scanf("%d",&n);
int dans=;
int a;
Read(a);
if(a<)
dans=-a,add(,,);
else
add(,a+,);
nn=max(nn,a+);
for(int i=,a;i<=n;i++)
{
Read(a);
if(a>=)
add(i,i+a+,);
nn=max(nn,i+a+);
add(i,i+,);
add(i+,i,);
}
for(int i=n+;i<=nn;i++)
{
add(i,i+,);
add(i+,i,);
}
s=;
e=n+;
dijkstra(s);
cout<<dis[e]+dans;
return ;
}

<DP+优化 Code>

#include<iostream>//乱搞
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; const int Max = ;
const int INF = 0x3f3f3f3f; struct node{
int val, pos;
node(){}
node(int a, int b){ val = a, pos = b;}
bool operator < (const node & X) const{
return val > X.val;
}
}; int N;
int A[Max + ], Dp[Max + ];
priority_queue<node>Q; bool getint(int & num){
char c; int flg = ; num = ;
while((c = getchar()) < '' || c > ''){
if(c == '-') flg = -;
if(c == -) return ;
}
while(c >= '' && c <= '' ){
num = num * + c - ;
if((c = getchar()) == -) return ;
}
num *= flg;
return ;
} int main(){
getint(N);
for(int i = ; i <= N; ++ i) getint(A[i - ]), A[i - ] += i;
Q.push(node(A[], A[]));
memset(Dp, 0x3f, sizeof Dp );
int minnum = INF;
for(int i = ; i <= N; ++ i){
while(! Q.empty() && Q.top().pos < i){
minnum = min(minnum, Q.top().val - * Q.top().pos);
Q.pop();
}
Dp[i] = min(Dp[i], minnum + i);
if(! Q.empty()) Dp[i] = min(Dp[i], Q.top().val - i);
Q.push(node(Dp[i] + A[i], A[i]));
}
printf("%d\n", Dp[N]);
return ;
}

业务 (business)

题目描述

Mr_H 谋得一份兼职——货车司机,从此以后他将会开着货车穿行在C 国的各大城市之间。
C 国中有n 座城市(编号为1~n),并且有m 条双向公路,每条公路连接两座不同的城市。货车从任意一座城市出发都可以抵达任意另一座城市。在每条公路上,都有一个收费站,通过的车辆需要交纳一定过路费。可能有多条公路连接相同的两座城市。
为了增加财政收入,C 国还在每座城市也设置了收费站。并且规定,车辆从一座城市到另一座城市的费用是,所经过公路费用和,加上所经过的城市中费用的次大值(这里的次大可以和最大相同,但是城市不同)。
现在Mr_H 告诉你今年k 次业务运送货物的起点、终点城市列表,请你帮忙计算,每次业务需要交纳的最低过路费。

输入

第一行包含三个用一个空格隔开的整数:n,m,k。其意义如题目描述。
第 2 到第 n+1 行:第i+1 行包含一个单独的整数 c(1<=c<=100000),表示城市i 的费用。
接下来的m 行,每行包含三个整数a,b,w,表示一条公路连接城市a 和城市b(1<=a,b<=n),其过路费为w(1<=w<=100000)。
最后的 k 行,每行包含两个整数:s,t,表示一次业务的起点和终点(1<=s,t<=n 且 s!=t)。

输出

共k 行,每行一个整数,表示从城市s 到t 的最少过路费。

样例数据

样例输入 样例输出

5 7 3
2
5
3
3
4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 3
1 4
2 3

4
7
8

<样例解释>

包含 5 个城市的样例图形如下:

●城市1 到城市3 的道路的“边过路费”为 2,“点过路费”为 2(城市2 的费用为次大)。所以总的花费为 2+2=4 。
●要从城市1 走到城市4 ,可以从城市1 走到城市3,再走到城市5,最后到达城市4 。如果这么走的话,需要的“边过路费”为 2+1+1=4,需要的点过路费为 3(城市3 或城市4 的点过路费次大),所以总的花费为 4+3=7。
●从城市2 走到城市3 的最佳路径是从城市2 出发,抵达城市5,最后到达城市3,这么走的话,边过路费为 3+1=4,点过路费为4,总花费为 4+4=8。

<数据范围>

对于 20%的数据,n<=10, m<=20
对于50%的数据,n<=100, m<=5000
对于100%的数据,1<=n<=250 , 1<=m<=10000 , 1<=k<=10000 ,其中有50%的数据点权没有重复。

解析

(考试的时候用的DFS,没D出来)

令:ans[x][y]=从x 到y 的最小过路费!计算ans[x][y]可以用DIJKstra 算法或SPFA 算法!
令:dist[i][0]=从k 出发到i 点经过的点费用最大值为a[k]的情况的最小边费用和;dist[i][1]=从k 出发到i 点经过的点费用次大值为a[k]的情况的最小边费用和
于是有: ans[x][y]=min{dist[x][0]+dist[y][1],dist[x][1]+dist[y][0]}+a[k]}其中 1<=k<=n
计算出ans[x][y]后,回答询问就很简单了。
时间复杂度 O(n2logm+k) (DIJKstra 堆优化后的时间复杂度)

Code

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue> #define MAXN 250
#define MAXM
#define DIST(x)(tmp[x.pos][x.hm])
#define VIS(x)(vis[x.pos][x.hm])
#define INF 0x3f3f3f3f using namespace std; typedef long long int LL; int getint()
{
int rn=;
char c=getchar();
while(c<''||''<c)
c=getchar();
while(''<=c&&c<='')
{
rn=rn*+c-'';
c=getchar();
}
return rn;
} int G[MAXN+][MAXN+];
int Val[MAXN+];
int dist[MAXN+][MAXN+];
int N,M,K; int tmp[MAXN+][];
bool vis[MAXN+][]; struct point
{
int pos,w;
bool hm;
point(){}
point(int a,bool b,int c){pos=a,hm=b,w=c;}
bool operator < (const point &a)const
{
return w>a.w;
}
}; priority_queue<point>que;
void insert(point newed)
{
if(DIST(newed)<newed.w)
return;
DIST(newed)=newed.w;
que.push(newed);
} void Dijkstra(int sc)
{
memset(tmp,0x3f,sizeof(tmp));
memset(vis,,sizeof(vis));
insert(point(sc,,));
point now,newed;
while(!que.empty())
{
now=que.top();
que.pop();
if(VIS(now))
continue;
else
VIS(now)=;
for(int v=;v<=N;++v)
if(G[now.pos][v])
{
newed.pos=v;
newed.hm=now.hm;
newed.w=DIST(now)+G[now.pos][v];
if(Val[v]>Val[sc])
{
if(now.hm)
continue;
else
{
newed.hm=;
insert(newed);
}
}
else if(Val[v]==Val[sc])
{
if(v==sc)
insert(newed);
else
{
insert(newed);
newed.hm=;
insert(newed);
}
}
else
insert(newed);
}
}
} int main()
{
scanf("%d%d%d",&N,&M,&K);
int i,j;
for(i=;i<=N;++i)
scanf("%d",&Val[i]);
int a,b,c;
for(i=;i<=M;++i)
{
scanf("%d%d%d",&a,&b,&c);
G[a][b]=(!G[a][b]||G[a][b]>c?c:G[a][b]);
G[b][a]=(!G[b][a]||G[b][a]>c?c:G[b][a]);
}
memset(dist,0x3f,sizeof(dist));
for(int sc=;sc<=N;++sc)
{
Dijkstra(sc); for(i=;i<=N;++i)
for(j=;j<=N;++j)
dist[i][j]=min(dist[i][j],min(tmp[i][]+tmp[j][],tmp[i][]+tmp[j][])+Val[sc]);
}
for(i=;i<=K;++i)
{
scanf("%d%d",&a,&b);
printf("%d\n",dist[a][b]);
}
return ;
}

Time: 2017-07-24

[SinGuaRiTy] 2017-07-24 NOIP2015 模拟赛的更多相关文章

  1. [SinGuLaRiTy] Nescafe 24杯模拟赛

    [SinGularLaRiTy-1044] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 小水塘(lagoon) 题目描述 忘川沧月的小水塘 ...

  2. 2017.6.11 NOIP模拟赛

    题目链接: http://files.cnblogs.com/files/TheRoadToTheGold/2017-6.11NOIP%E6%A8%A1%E6%8B%9F%E8%B5%9B.zip 期 ...

  3. 2017冬季24集训模拟题-24星球的末日(Floyd)

    24 星球的末日[问题描述]24 星球的世界末日就要到了 , 可是诺亚方舟还没有制造完成 . 为了制造诺亚方舟这个星球上的所有国家都站在统一战线 . 现在一共有n个国家 , 一个国家到另一个国家都有一 ...

  4. 2017.10.3 QBXT 模拟赛

    题目链接 T1 模拟 #include <cstring> #include <cstdio> #define N 105000 int L,R; char s[N]; int ...

  5. 计蒜客 2017 NOIP 提高组模拟赛(四)Day1 T2 小X的密室

    https://nanti.jisuanke.com/t/17323 小 X 正困在一个密室里,他希望尽快逃出密室. 密室中有 N 个房间,初始时,小 X 在 1号房间,而出口在 N号房间. 密室的每 ...

  6. 【资料下载区】【iCore系列及其它模块相关文档】更新日期2017/07/24

    iCore系列双核心板原理图下载区 iCore双核心板原理图下载(注释版)iCore1s双核心板原理图下载iCore2双核心板原理图下载iCore3双核心板原理图下载iCore4双核心板原理图下载 i ...

  7. EZ 2018 06 24 NOIP2018 模拟赛(二十)

    很久之前写的一套题了,由于今天的时间太多了,所以记起来就写掉算了. 这一场尽管T2写炸了,但也莫名Rank4涨了Rating.不过还是自己太菜. A. 环游世界 首先我们先排个序,想一下如果不用走回来 ...

  8. EZ 2018 07 06 NOIP模拟赛

    又是慈溪那边给的题目,这次终于没有像上次那样尴尬了, T1拿到了较高的暴力分,T2没写炸,然后T3写了一个优雅的暴力就203pts,Rank3了. 听说其它学校的分数普遍100+,那我们学校还不是强到 ...

  9. 2017 10.25 NOIP模拟赛

    期望得分:100+40+100=240 实际得分:50+40+20=110 T1 start取了min没有用,w(゚Д゚)w    O(≧口≦)O T3 代码3个bug :数组开小了,一个细节没注意, ...

随机推荐

  1. -3dB的理解

    -3dB到底是什么?集成运放-3dB带宽又是什么? 以无源高通电路为例,介绍-3dB的意义. 输出与输入只比: Au=Uo/Ui=R/(R+1/j*2*PI*f*C)=1/(1+1/j*2*PI*f* ...

  2. XSS自动化检测 Fiddler Watcher & x5s & ccXSScan 初识

    一.标题:XSS 自动化检测 Fiddler Watcher & x5s  & ccXSScan 初识     automated XSS testing assistant 二.引言 ...

  3. Oracle data guard 10g 搭建

    Oracle data guard 10g 搭建 1系统常规参数检查 硬盘 [root@localhost ~]# df -h 内核 [root@localhost ~]# uname -a [roo ...

  4. DripRoad(点滴之路)

    关于DripRoad DripRoad 意为点滴之路,程序员之路在于点滴积累!是的,这些积累包括技术能力,沟通能力,业务能力等等.   我 我是唐志伟,2009年一个人来上海,就读于上海医疗器械高等专 ...

  5. CAD库中列举所有航路点

    select distinct f1.airway_point_name,f1.latitude,f1.longitude,upper(f1.airway_point_type_name)type,f ...

  6. vsftpd 被动模式与主动模式

    vsftpd 被动模式与主动模式 VSFTP文件与目录/usr/sbin/vsftp vsftp的主程序/etc/rc.d/init.d/vsftp vsftp的启动脚本/etc/vsftpd/vsf ...

  7. 将openfire部署到CentOS云服务器上

    http://ishere.cn/2014/07/25/centos-64bit-openfire.html      CentOS 64位安装openfire http://www.cnblogs. ...

  8. TypeError: 'append' called on an object that does not implement interface FormData 解决方法

    使用ajax提交form表单时,$("formId").serialize()不能提交type="file"类型的input,这个时候可以选择使用FormDat ...

  9. 【Android异常】The specified child already has a parent. You must call removeView() on the child's parent first.

    错误信息: Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must ...

  10. NLP整体流程的代码

    import nltk import numpy as np import re from nltk.corpus import stopwords # 1 分词1 text = "Sent ...