T1

Description

给定一个n个点m条边的有向图,有k个标记点,要求从规定的起点按任意顺序经过所有标记点到达规定的终点,问最短的距离是多少。

Input

第一行5个整数n、m、k、s、t,表示点个数、边条数、标记点个数、起点编号、终点编号。

接下来m行每行3个整数x、y、z,表示有一条从x到y的长为z的有向边。

接下来k行每行一个整数表示标记点编号。

Output

输出一个整数,表示最短距离,若没有方案可行输出-1。

Sample Input

3 3 2 1 1

1 2 1

2 3 1

3 1 1

2

3

Sample Output

3

【样例解释】

路径为1->2->3->1。

Data Constraint

20%的数据n<=10。

50%的数据n<=1000。

另有20%的数据k=0。

100%的数据n<=50000,m<=100000,0<=k<=10,1<=z<=5000。

解题思路

考场上一时抽风写了个最短路套状压初值还没附好,50分。。正解应该是将必须经过的点两两之间的最短路求出来之后dfs

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define int long long using namespace std;
const int MAXN = 50005;
const int inf = 0x3f3f3f3f3f3f3f3f; int n,m,k,S,T,go[MAXN],ans=0x3f3f3f3f3f3f3f3f;
int head[MAXN],cnt,tot;
int to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
int dis[15][MAXN],id[MAXN],dp[(1<<11)+5][15];
bool vis[MAXN],must[MAXN],use[MAXN];
queue<int> Q; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} inline void add(int bg,int ed,int w){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt,val[cnt]=w;
} inline void spfa(int x){
memset(vis,false,sizeof(vis));
dis[++tot][x]=0;vis[x]=1;Q.push(x);
while(!Q.empty()){
int x=Q.front();Q.pop();
for(register int i=head[x];i;i=nxt[i]){
int u=to[i];
if(dis[tot][x]+val[i]<dis[tot][u]) {
dis[tot][u]=dis[tot][x]+val[i];
if(!vis[u]) {
vis[u]=1;
Q.push(u);
}
}
}
vis[x]=0;
}
} inline void dfs(int x,int now,int sum){
if(sum>ans) return;
if(now==k) {ans=min(ans,sum+dis[id[x]][T]);return;}
for(register int i=1;i<=k;i++){
if(use[i]) continue;
use[i]=1;
dfs(go[i],now+1,sum+dis[id[x]][go[i]]);
use[i]=0;
}
} signed main(){
memset(dp,0x3f,sizeof(dp));
memset(dis,0x3f,sizeof(dis));
n=rd();m=rd();k=rd();S=rd();T=rd();
for(register int i=1;i<=m;i++){
int x=rd(),y=rd(),z=rd();
add(x,y,z);
}
for(register int i=1;i<=k;i++){
int x=rd();must[x]=1;id[x]=i;go[i]=x;
spfa(x);
}
if(!must[S]) spfa(S),id[S]=k+1;
for(register int i=1;i<=k;i++){
memset(use,false,sizeof(use));
if(dis[id[S]][go[i]]==inf) continue;
use[i]=1;
if(must[S] && go[i]!=S)
dfs(go[i],2,dis[id[S]][go[i]]);
else if(!must[S])
dfs(go[i],1,dis[id[S]][go[i]]);
}
if(k==0) ans=dis[id[S]][T];
if(ans==inf) ans=-1;
cout<<ans<<endl;
return 0;
}

T2

Description

万老师听说某大国很流行穿越,于是他就想写一个关于穿越的剧本。

闲话休提。话说老师穿越到了某一个剑与魔法的大陆。因为如此这般,所以老师从维娜艾那里得到了预言。老师一共被告知了若干件按顺序结算的事件。这些事件分为两类:战役事件(CASE)、穿越回去事件(END)。战役事件可以选择是否参加,参加了之后会获得一定的金钱。每个END事件发生需要至少参加一定数量的战役事件。特别的是,END事件如果满足要求就会强制发生。老师希望在大陆玩个够,所以他要求只有最后一个END事件会发生。老师希望获得最多的金钱,所以求助于你。

Input

第一行一个数N,表示输入文件有多少行。

接下来每一行用空格隔开一个字符和一个整数。字符为“c”表示战役事件,接下来的整数表示这次涨RP顺带有多少钱;字符为“e”表示穿越回去事件,接下来的整数代表至少要涨多少RP。最后一个事件保证是END事件。

Output

第一行一个整数,最多金钱数目。

若不可能则输出-1。

Sample Input

5

c 10

c 12

e 2

c 1

e 2

Sample Output

13

Data Constraint

30%的数据满足 N<=20

60%的数据满足 N<=1,000

100%的数据满足 N<=200,000

每次涨RP事件赏金不超过10,000

穿越事件的要求不超过200,000

解题思路

最后的战役事件竟然能超了最后的end!!!我太菜了还以为能相等。。。写了两个小时的线段树+对拍结果0分。。又是一道由100 变成 0的好题。正解是优先队列+贪心。我用的线段树直接先排序,然后每次挑最大的相当于区间修改,从这个战役之后的第一个一直到倒数第二个这段区间-1。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std;
const int MAXN = 200005;
const int inf = 0x3f3f3f3f; int n,cnt1,cnt2,ans,mn[MAXN<<1];
int sum[MAXN<<1],lazy[MAXN<<1]; struct Data{
int id,a;
}data[3][MAXN]; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} inline bool cmp(Data A,Data B){
return A.a>B.a;
} inline void pushdown(int x,int ln,int rn){
lazy[x<<1]+=lazy[x];
lazy[x<<1|1]+=lazy[x];
sum[x<<1]+=ln*lazy[x];
sum[x<<1|1]+=rn*lazy[x];
mn[x<<1]+=lazy[x];
mn[x<<1|1]+=lazy[x];
lazy[x]=0;
} inline void build(int x,int l,int r){
if(l==r){
sum[x]=data[2][l].a;
mn[x]=data[2][l].a;
lazy[x]=0;
return ;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
sum[x]=sum[x<<1]+sum[x<<1|1];
mn[x]=min(mn[x<<1],mn[x<<1|1]);
} inline void update(int x,int l,int r,int L,int R,int k){
if(L<=l && r<=R){
sum[x]+=k;mn[x]+=k;lazy[x]+=k;
return ;
}
int mid=l+r>>1;
if(lazy[x]) pushdown(x,mid-l+1,r-mid);
if(mid>=L) update(x<<1,l,mid,L,R,k);
if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
sum[x]=sum[x<<1]+sum[x<<1|1];
mn[x]=min(mn[x<<1],mn[x<<1|1]);
} inline int query(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return mn[x];
int ret=0x3f3f3f3f;
int mid=l+r>>1;
if(lazy[x]) pushdown(x,mid-l+1,r-mid);
if(mid>=L) ret=min(ret,query(x<<1,l,mid,L,R));
if(mid<R) ret=min(ret,query(x<<1|1,mid+1,r,L,R));
return ret;
} int main(){
n=rd();
for(register int i=1;i<=n;i++){
char c;cin>>c;int x=rd();
if(c=='c') data[1][++cnt1].a=x,data[1][cnt1].id=i;
else data[2][++cnt2].a=x,data[2][cnt2].id=i;
}
build(1,1,cnt2);
sort(data[1]+1,data[1]+1+cnt1,cmp);
for(register int i=1;i<=cnt1;i++){
int ID=data[1][i].id;int x=data[1][i].a;
int l=1,r=cnt2;int now;
while(l<=r){
int mid=l+r>>1;
if(data[2][mid].id<ID) l=mid+1;
else {
now=mid;
r=mid-1;
}
}
int res;
if(now>cnt2-1) res=inf;
else res=query(1,1,cnt2,now,cnt2-1);
if(res>1 || now==cnt2){
ans+=x;
if(now!=cnt2)
update(1,1,cnt2,now,cnt2-1,-1);
}
}
cout<<ans<<endl;
return 0;
}

T3

Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits

Goto ProblemSet

Description

平面上有n个点,求出用这些点可以构成的三角形数。

Input

第一行一个整数n。

接下来n行,每行两个整数,表示点的坐标。

Output

输出仅一个整数,表示所求答案。

Sample Input

5

0 0

1 1

1 -1

-1 -1

-1 1

Sample Output

8

Data Constraint

对于50%的数据,n<=300。

对于100%的数据,n<=3000,坐标的绝对值不超过10^4,保证没有重合的点。

解题思路

这道题跟以前做过的数三角形好像啊,结果还是打的暴力。。用容斥的思想,每次枚举一个点,然后枚举其余点算斜率,之后排个序用组合数学。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define int long long using namespace std;
const int MAXN = 3005;
const double inf = 1e10+1;
const double eps = 1e-12; int n,x[MAXN],y[MAXN],sum,cnt;
double slp[MAXN]; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} signed main(){
freopen("triangle.in","r",stdin);
freopen("triangle.out","w",stdout);
n=rd();sum=n*(n-1)*(n-2)/6;
for(register int i=1;i<=n;i++)
x[i]=rd(),y[i]=rd();
for(register int i=1;i<=n;i++){
memset(slp,0,sizeof(slp));cnt=0;
for(register int j=i+1;j<=n;j++){
if(y[i]==y[j]) slp[++cnt]=inf;
else if(x[i]==x[j]) slp[++cnt]=-inf;
else slp[++cnt]=(double)(x[i]-x[j])/(y[i]-y[j]);
}
sort(slp+1,slp+1+cnt);
int now=1;slp[0]=-inf-5;
for(register int j=1;j<=cnt;j++){
if(fabs(slp[j]-slp[j-1])>eps){
sum-=now*(now-1)/2;
now=1;
}
else now++;
}
sum-=now*(now-1)/2;
}
printf("%lld",sum);
return 0;
}

2018.8.6 模拟赛 提高组B的更多相关文章

  1. [2018.8.12]模拟赛B组

    T1 打表出奇迹,发现结论为\(E(a_n)=n+1\)即可. #include <iostream> #include <cstdio> #include <cctyp ...

  2. 2018.12.30【NOIP提高组】模拟赛C组总结

    2018.12.30[NOIP提高组]模拟赛C组总结 今天成功回归开始做比赛 感觉十分良(zhōng)好(chà). 统计数字(count.pas/c/cpp) 字符串的展开(expand.pas/c ...

  3. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

  4. 2017.1.16【初中部 】普及组模拟赛C组总结

    2017.1.16[初中部 ]普及组模拟赛C组 这次总结我赶时间,不写这么详细了. 话说这次比赛,我虽然翻了个大车,但一天之内AK,我感到很高兴 比赛 0+15+0+100=115 改题 AK 一.c ...

  5. NOIP2020 模拟赛 B 组 Day6

    非常巧妙的一场模拟赛,比较偏向于 Atcoder 的风格,考场上做出了 A .C 两题. A. 礼物购买 排完序后一个个礼物地枚举时间复杂度是\(\Theta(nm)\)的,不能接受.但是注意到,若当 ...

  6. 2018.10.17NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 +100\) 实际得分:\(100 + 100 + 60\) 辣鸡模拟赛.. 5min切掉T1,看了一下T2 T3,感觉T3会被艹爆因为太原了.. 淦了20 ...

  7. 2017.07.06【NOIP提高组】模拟赛B组

    Summary 今天比赛感觉题目很奇葩,都可以用许多简单方法来做,正确性都显然,当然也有点水,也就是说是考我们的数感和数学知识,而程序,只是代码的体现. 这次的时间安排感觉不错,因为很快就打完最后一道 ...

  8. 2018 蓝桥杯省赛 B 组模拟赛(五)

    A模拟 代码1 #include<bits/stdc++.h> using namespace std; int n = 101; int a[120][120]; int ans = 0 ...

  9. 2017.08.08【NOIP提高组】模拟赛B组

    Summary 今天的题目也不算很难,唯一一道没做出来的题目是以前做过的,太不应该了. Problem T1 油滴扩展 题目大意 给你一堆点,你准备要在这么多的点当中滴油.你可以自己安排顺序,每次滴油 ...

随机推荐

  1. 记录下sparkStream的做法(scala)

    一直用storm做实时流的开发,之前系统学过spark但是一直没做个模版出来用,国庆节有时间准备做个sparkStream的模板用来防止以后公司要用.(功能模拟华为日常需求,db入库hadoop环境) ...

  2. mybatis配合pagehelper分页助手查询

    Maven: 参考: springBoot2.x整合pagehelper5.1.2:https://blog.csdn.net/Carlson_Chis/article/details/8563748 ...

  3. MaxCompute问答整理之8月

    本文是基于对MaxCompute产品的学习进度,再结合开发者社区里面的一些问题,进而整理成文.希望对大家有所帮助. 问题一.通过数据源数据增量同步后,如何查看某一条数据具体被同步到MaxCompute ...

  4. 【HAOI2015】树上染色—树形dp

    [HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...

  5. xshell添加脚本

    ##### xshell添加脚本```属性连接 - 用户身份验证 - 登陆脚本 - 添加等待:[usmshell]$发送:open 212 //212是指188那台机器的ID再添加一个等待:passw ...

  6. Java面试总结-基础篇1

    java多线程-- 自旋锁,偏向锁 好处:可以举Servlet和CGI的对比用户线程和守护线程的区别:用户线程结束后JVM会退出,然后守护线程才会终止(比如垃圾回收线程),如何在java中创建守护线程 ...

  7. springmvc 串口读写 基于win7使用txrx netbeans jdk1.8 maven的

    引入 <dependency> <groupId>org.rxtx</groupId> <artifactId>rxtx</artifactId& ...

  8. VC++1.5太伟大了

    功能样样俱全,一点不比现在的VS系列差 VC++1.5全貌,虽然很古老,但是已经可以了. 新建的文档试图,多文档工程,很像样 文档试图,单文档工程,已经非常像样了,和记事本差不多了 这是资源编辑器,寒 ...

  9. 免费提取百度文库 doc 文件

    首先说明,今天要推荐的这款软件,不能不能不能免费提取百度文库里 PDF 格式的文件. 对于其他的格式,无论收费与否都能免费提取. 只是口头说说免不了耍流氓的嫌疑,举栗如下: 百度文库里<喜迎党的 ...

  10. jsonp 请求报Uncaught SyntaxError: Unexpected token :

    $(document).ready(function() { jQuery.ajax({ type: 'GET', url: 'http://wncrunners.com/admin/colors.j ...