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. PAT甲级——A1077 Kuchiguse

    The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...

  2. 【转载】unittest总结

    本文转载链接:http://www.cnblogs.com/yufeihlf/p/5707929.html unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执 ...

  3. CentOS 6.5 源码编译搭建LAMP(两台独立主机实现)

    搭建前准备: 1.两台独立主机 httpd:192.168.1.105 php-fpm:192.168.1.105 mariadb:192.168.1.103 2.相关软件的源码包 httpd:htt ...

  4. 长按触发(PC端和移动端)

    $.fn.longPress = function(fn) { var timeout = undefined; var $this = this; for(var i = 0;i<$this. ...

  5. 大数据处理也要安全--关于MaxCompute的安全科普

    [TOC] 1.企业大数据处理现状 当今社会数据收集手段不断丰富,行业数据大量积累,数据规模已增长到了传统软件行业无法承载的海量数据(百GB.TB乃至PB)级别.基于此,阿里云推出有了一套快速.完全托 ...

  6. Opencv Mat矩阵操作注意事项

    矩阵操作通常不会进行元素复制,应注意: Mat a=Mat(100,100,CV_32S); Mat b=Mat(100,100,CV_32S); b=a.col(8);//此时并未进行元素赋值,而只 ...

  7. JS创建和存储 cookie的一些方法

    在js中cookie的操作与存储及清除cookie都与时间有关,我们只要把cookie过期时间进行有效的设置我们就可以控制它的存储了,下面我来给大家总结一下js中cookie的一些使用技巧 创建和存储 ...

  8. PAT甲级——A1031 Hello World for U

    Given any string of N (≥) characters, you are asked to form the characters into the shape of U. For ...

  9. Jquery选择器总结一

    jquery 是javaScript框架,封装了js. 好处:使用方便,少代码多功能. 实现同一个功能的代码量少. 屏蔽浏览器差异. 简化ajax开发. 选择器 基本选择器 1. id选择器 $(&q ...

  10. 初探.NET CORE WEB API(RESTful风格)

    前面有4篇系列博客 (一)Asp.net web api中的坑-[找不到与请求 URI匹配的 HTTP 资源] (二)Asp.net web api中的坑-[http get请求中的参数] (三)As ...