noip2017部分题目
D1T3 逛公园
题目描述
策策同学特别喜欢逛公园。公园可以看成一张NN个点MM条边构成的有向图,且没有 自环和重边。其中1号点是公园的入口,NN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间。
策策每天都会去逛公园,他总是从1号点进去,从NN号点出来。
策策喜欢新鲜的事物,它不希望有两天逛公园的路线完全一样,同时策策还是一个 特别热爱学习的好孩子,它不希望每天在逛公园这件事上花费太多的时间。如果1号点 到NN号点的最短路长为dd,那么策策只会喜欢长度不超过d + Kd+K的路线。
策策同学想知道总共有多少条满足条件的路线,你能帮帮它吗?
为避免输出过大,答案对PP取模。
如果有无穷多条合法的路线,请输出-1−1。
输入输出格式
输入格式:
第一行包含一个整数 TT, 代表数据组数。
接下来TT组数据,对于每组数据: 第一行包含四个整数 N,M,K,PN,M,K,P,每两个整数之间用一个空格隔开。
接下来MM行,每行三个整数a_i,b_i,c_iai,bi,ci,代表编号为a_i,b_iai,bi的点之间有一条权值为 c_ici的有向边,每两个整数之间用一个空格隔开。
输出格式:
输出文件包含 TT 行,每行一个整数代表答案。
输入输出样例
2
5 7 2 10
1 2 1
2 4 0
4 5 2
2 3 2
3 4 1
3 5 2
1 5 3
2 2 0 10
1 2 0
2 1 0
3
-1
说明
【样例解释1】
对于第一组数据,最短路为 33。 $1 – 5, 1 – 2 – 4 – 5, 1 – 2 – 3 – 5$ 为 33 条合法路径。
【测试数据与约定】
对于不同的测试点,我们约定各种参数的规模不会超过如下
测试点编号 | TT | NN | MM | KK | 是否有0边 |
---|---|---|---|---|---|
1 | 5 | 5 | 10 | 0 | 否 |
2 | 5 | 1000 | 2000 | 0 | 否 |
3 | 5 | 1000 | 2000 | 50 | 否 |
4 | 5 | 1000 | 2000 | 50 | 否 |
5 | 5 | 1000 | 2000 | 50 | 否 |
6 | 5 | 1000 | 2000 | 50 | 是 |
7 | 5 | 100000 | 200000 | 0 | 否 |
8 | 3 | 100000 | 200000 | 50 | 否 |
9 | 3 | 100000 | 200000 | 50 | 是 |
10 | 3 | 100000 | 200000 | 50 | 是 |
对于 100%的数据, 1 \le P \le 10^9,1 \le a_i,b_i \le N ,0 \le c_i \le 10001≤P≤109,1≤ai,bi≤N,0≤ci≤1000。
数据保证:至少存在一条合法的路线。
题意:求dis(1,n)<=dis(1,n)+k 的路径数
设f[u][k]表示比 dis(1,u) 长度多 k 的路径数,则
dp[v][k] = ∑dp[u][k+ dis[u]+w-dis[v]] ((u,v)∈E) //dis[i]表示从起点到点i的最短距离,w是(u,v)边权
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define R register
#define NN 100001
#define MM 200001
using namespace std;
int T,N,M,K,P;
int head[NN],d[NN],f[NN][],b[NN][],ans;
bool vis[NN],flag;
struct edge{
int u,v,w,next;
}e[MM];
inline int ri(){
char c=getchar();int x=,w=;
while(!isdigit(c)){if(c=='-')w=-;c=getchar();}
while( isdigit(c)){x=(x<<)+(x<<)+c-;c=getchar();}
return x*w;
}
inline void spfa(){
queue<int> q;
d[]=;
q.push();
int u;
while(!q.empty()){
u=q.front();q.pop();
vis[u]=;
for(R int i=head[u];i;i=e[i].next){
if(d[e[i].v]>d[u]+e[i].w){
d[e[i].v]=d[u]+e[i].w;
if(!vis[e[i].v])vis[e[i].v]=,q.push(e[i].v);
}
}
}
}
inline int dfs(int u,int step){
if(b[u][step]==||flag)return flag=;
if(b[u][step]==)return f[u][step];
b[u][step]=;
for(R int i=head[u],w;i;i=e[i].next){
w=step+d[u]-d[e[i].v]-e[i].w;
if(w>K||w<)continue;
f[u][step]+=dfs(e[i].v,w);
f[u][step]%=P;
}
b[u][step]=;
return f[u][step];
}
int main(){
T=ri();
while(T--){
N=ri(),M=ri(),K=ri(),P=ri();
memset(head,,sizeof(head)); for(R int i=;i<=M;++i){
e[i].u=ri(),e[i].v=ri(),e[i].w=ri();
e[i].next=head[e[i].u];
head[e[i].u]=i;
}//以上输入 memset(vis,,sizeof(vis));
memset(d,,sizeof(d));
spfa();//跑一边spfa找最短路 memset(head,,sizeof(head));
for(R int i=;i<=M;++i){
swap(e[i].u,e[i].v);
e[i].next=head[e[i].u];
head[e[i].u]=i;//反向连图
} memset(f, , sizeof(f));
memset(b, , sizeof(b));
f[][]=,ans=,flag=; for(R int i=;i<=K;++i){//枚举与mindis的差
ans+=dfs(N,i); //倒着搜
ans%=P;
}
printf("%d\n", flag ? - : ans);
}
return ;
}
D2T1 奶酪
题目描述
现有一块大奶酪,它的高度为 hhh,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z=0z = 0z=0,奶酪的上表面为z=hz = hz=h。
现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐 标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别 地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果 一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?
空间内两点P1(x1,y1,z1)P_1(x_1,y_1,z_1)P1(x1,y1,z1)、P2(x2,y2,z2)P2(x_2,y_2,z_2)P2(x2,y2,z2)的距离公式如下:
dist(P1,P2)=(x1−x2)2+(y1−y2)2+(z1−z2)2\mathrm{dist}(P_1,P_2)=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2}dist(P1,P2)=(x1−x2)2+(y1−y2)2+(z1−z2)2
输入输出格式
输入格式:
每个输入文件包含多组数据。
的第一行,包含一个正整数 TTT,代表该输入文件中所含的数据组数。
接下来是 TTT 组数据,每组数据的格式如下: 第一行包含三个正整数 n,hn,hn,h 和 rrr,两个数之间以一个空格分开,分别代表奶酪中空 洞的数量,奶酪的高度和空洞的半径。
接下来的 nnn 行,每行包含三个整数 x,y,zx,y,zx,y,z,两个数之间以一个空格分开,表示空 洞球心坐标为(x,y,z)(x,y,z)(x,y,z)。
输出格式:
TTT 行,分别对应 TTT 组数据的答案,如果在第 iii 组数据中,Jerry 能从下 表面跑到上表面,则输出Yes
,如果不能,则输出No
(均不包含引号)。
输入输出样例
3
2 4 1
0 0 1
0 0 3
2 5 1
0 0 1
0 0 4
2 5 2
0 0 2
2 0 4
Yes
No
Yes
说明
【输入输出样例 1 说明】
第一组数据,由奶酪的剖面图可见:
第一个空洞在(0,0,0)(0,0,0)(0,0,0)与下表面相切
第二个空洞在(0,0,4)(0,0,4)(0,0,4)与上表面相切 两个空洞在(0,0,2)(0,0,2)(0,0,2)相切
输出 Yes
第二组数据,由奶酪的剖面图可见:
两个空洞既不相交也不相切
输出 No
第三组数据,由奶酪的剖面图可见:
两个空洞相交 且与上下表面相切或相交
输出 Yes
【数据规模与约定】
对于 20%20\%20%的数据,n=1n = 1n=1,1≤h1 \le h1≤h , r≤10,000r \le 10,000r≤10,000,坐标的绝对值不超过 10,00010,00010,000。
对于 40%40\%40%的数据,1≤n≤81 \le n \le 81≤n≤8, 1≤h1 \le h1≤h , r≤10,000r \le 10,000r≤10,000,坐标的绝对值不超过 10,00010,00010,000。
对于80%80\%80%的数据, 1≤n≤1,0001 \le n \le 1,0001≤n≤1,000, 1≤h,r≤10,0001 \le h , r \le 10,0001≤h,r≤10,000,坐标的绝对值不超过10,00010,00010,000。
对于 100%100\%100%的数据,1≤n≤1,0001 \le n \le 1,0001≤n≤1,000,1≤h,r≤1,000,000,0001 \le h , r \le 1,000,000,0001≤h,r≤1,000,000,000,T≤20T \le 20T≤20,坐标的 绝对值不超过 1,000,000,0001,000,000,0001,000,000,000。
emm 以下的代码不是原创 忘记了是哪里copy来的
考虑并查集。如果一个能到达奶酪顶的空洞和一个能到达奶酪底的空洞有交,便可以。即有共同的祖先。
当然我并不知道会不会有一个洞连接了奶酪顶和底...这不重要 这样的洞父亲就是本身
#include<bits/stdc++.h>
#define ll long long
#define R register
using namespace std;
int f[];
int find(int x){
return f[x]==x ? x : f[x]=find(f[x]);
}
double dis(long long x,long long y,long long z,long long x1,long long y1,long long z1){
return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)+(z-z1)*(z-z1));
}
long long x[],y[],z[];
int f1[],f2[];
int main(){
int t,n,h;long long r;
scanf("%d",&t);
for (int i=;i<=t;i++){
scanf("%d%d%ld",&n,&h,&r);
int tot1=;int tot2=;
for (R int j=;j<=n;j++)f[j]=j;
for (R int j=;j<=n;j++){
scanf("%ld%ld%ld",&x[j],&y[j],&z[j]);
if (z[j]+r>=h)f1[++tot1]=j;
if (z[j]-r<=)f2[++tot2]=j;
for (R int k=;k<=j;k++){
if (dis(x[j],y[j],z[j],x[k],y[k],z[k])<=*r){
int a1=find(j),a2=find(k);
if (a1!=a2)f[a1]=a2;
}
}
}
int s=;
for (int j=;j<=tot1;j++){
for (int k=;k<=tot2;k++)
if (find(f1[j])==find(f2[k])){s=; break;}
if (s==) break;
}
if (s==) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return ;
}
noip2017部分题目的更多相关文章
- 关于$NOIP2017$的题目讲解
关于\(NOIP2017\)的题目讲解 1.小凯的疑惑 题目描述: 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法 ...
- [Luogu 3952] NOIP2017 时间复杂度
[Luogu 3952] NOIP2017 时间复杂度 一年的时间说长不长,说短,也不短. 一年之内无数次觉得难得可怕的题目,原来也就模拟这么回事儿. #include <cstdio> ...
- [NOIP2017]宝藏 状压DP
[NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...
- [NOIP2017]列队 离线+SBT
[NOIP2017]列队 题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵 ...
- NOIP2017宝藏 [搜索/状压dp]
NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- 「LOJ 6373」NOIP2017 普及组题目大融合
NOIP2017 普及组题目大融合 每个读者需要有某个后缀的书,可以暴力map,复杂度\(o(9*nlog(n))\),也可以反串建trie树,复杂度\(o(9*n)\). 故可以求出需要的最少的RM ...
- 【qboi冲刺NOIP2017复赛试题4】 全套题目+题解+程序
作为一个好人(验题人),我给大家奉上下这套题的题解,并且预祝大家这套题能够AK: T1题面:Alice现在有n根木棍,他们长度为1,2,3....n,Bob想把某一些木棍去掉,使得Alice剩下的木棍 ...
- NOIP2017普及组解题报告
刚参加完NOIP2017普及,只考了210,于是心生不爽,写下了这篇解题报告...(逃 第一次写博,望dalao们多多指导啊(膜 第一题score,学完helloworld的人也应该都会吧,之前好多人 ...
- [SinGuLaRiTy] NOIP2017 提高组
[SinGuLaRiTy-1048] Copyright (c) SinGuLaRiTy 2018. All Rights Reserved. NOIP2017过了这么久,现在2018了才找到寒假这么 ...
随机推荐
- DSAPI官方QQ群
DSAPI官方QQ群 请加主群,若主群成员已满,请加分群. 群内除常规的.NET技术交流外,也负责DSAPI的使用技术支持和更新通知. 『VB.NET/C#编程』主群 ...
- js将一个数组分成多个数组
1,将数组array分成长度为subGroupLength的小数组并返回新数组 function group(array, subGroupLength) { let index = 0; let n ...
- git 提交项目代码到码云步骤 以及出现错误解决办法
git initgit remote add origin 项目地址git add .git commit -m "注释"git push origin master 出现错误 $ ...
- android 卡顿 Matrix TraceCanary
转载: 通过观察大盘整体的帧率及掉帧程度,来评估并监控一些重要场景的流畅性.通过一个闭环的流程,利用 Matrix-TraceCanary 模块从客户端对卡顿进行捕捉与分析上报,通过后台聚类问题堆栈及 ...
- 网络爬虫BeautifulSoup库的使用
使用BeautifulSoup库提取HTML页面信息 #!/usr/bin/python3 import requests from bs4 import BeautifulSoup url='htt ...
- python高级(4)—— 虚拟环境安装使用
虚拟环境 什么是虚拟环境 对电脑稍微有点常识的朋友相信都玩过,比如VMware,virtualbox,或者你用电脑端的模拟器玩手机端的游戏也是一样,其实就是一个假的空间,在Python这里,虚拟环境就 ...
- Linux学习历程——Centos 7 chown命令
一.命令介绍 Linux是多人多工操作系统,所有的文件皆有拥有者.利用 chown 将指定文件的拥有者改为指定的用户或组, 用户可以是用户名或者用户ID:组可以是组名或者组ID:文件是以空格分开的要改 ...
- Lua rawget rawset newindex 函数定义和例子
在绝大多数情况下,我们都不会用到rawget和rawset. 本文的运行环境:lua 5.3 for windows rawset 赋值操作 rawset是在设置值的过程,进行处理,比如:当某个值改变 ...
- java加载properties文件的六中基本方式实现
java加载properties文件的方式主要分为两大类:一种是通过import java.util.Properties类中的load(InputStream in)方法加载: 另一种是通过impo ...
- java拦截器(interceptor)
1.声明式 (1)注解,使用Aspect的@Aspect (2)实现HandlerInterceptor /** * 拦截请求 * * @author Administrator * */ @Comp ...