赞
踩
题意:
给定一个数列
{
a
n
}
\{a_n\}
{an} ,问
d
∣
∏
i
=
l
r
a
i
d\mid\prod\limits_{i=l}^{r}a_i
d∣i=l∏rai 是否成立,其中
d
,
l
,
r
d,l,r
d,l,r 都是给定正整数。
题解见队友博客,点击查看。
题意:
求满足
n
a
⌈
log
2
n
⌉
b
⩽
k
n^a\lceil\log_2n\rceil^b\leqslant k
na⌈log2n⌉b⩽k 的整数
n
n
n 的最大值,其中
a
,
b
⩽
10
,
1
0
6
⩽
k
⩽
1
0
18
a,b\leqslant 10,10^6\leqslant k\leqslant 10^{18}
a,b⩽10,106⩽k⩽1018 是给定正整数。
题解见队友博客,点击查看。
题意:
给定一个有
m
m
m 条边的
n
n
n 顶有向图,其中任意一条从
u
i
u_i
ui 到
v
i
v_i
vi 的边具有两个相关值
a
i
,
b
i
a_i,b_i
ai,bi 。现欲从顶点
1
1
1 走到顶点
n
n
n ,每次经过一条边
e
i
e_i
ei 的时候都要判断
cost
=
log
2
level
+
a
i
level
⩾
b
i
\text{cost}=\log_2\frac{\text{level}+a_i}{\text{level}}\geqslant b_i
cost=log2levellevel+ai⩾bi 是否成立,成立才能通行。其中
level
\text{level}
level 的初始值为
1
1
1 ,且每经过一条边
e
i
e_i
ei 都要增长
a
i
a_i
ai 。
问是否存在从结点
1
1
1 到结点
n
n
n 的最短路径,如果存在,求最小总
cost
\text{cost}
cost 。
解法:
包装过的单源最短路径问题。
我们可以将到达结点
i
i
i 时的
level
∣
i
\text{level}\mid_i
level∣i 写成
1
+
∑
j
∈
G
π
,
i
a
j
1+\sum\limits_{j\in G_{\pi,i}} a_j
1+j∈Gπ,i∑aj ,其中
G
π
,
i
G_{\pi,i}
Gπ,i 表示顶点
i
i
i 在最短路径上的前驱子图。若记结点
i
i
i 在最短路径上的后继结点为
i
′
i'
i′ ,则总的
cost
\text{cost}
cost 就可以写为
∑
i
log
2
1
+
∑
j
∈
G
π
,
i
a
j
+
a
i
1
+
∑
j
∈
G
π
,
i
a
j
=
log
2
(
∏
i
1
+
∑
j
∈
G
π
,
i
′
a
j
1
+
∑
j
∈
G
π
,
i
a
j
)
=
log
2
(
1
+
∑
j
∈
G
π
,
n
a
j
)
=
log
2
(
level
∣
n
)
因此,只要求解以结点 1 1 1 为起点,以各边的 a i a_i ai 值为边权的单源最短路径即可。
值得注意的是,松弛过程中要记得判断当前边是否可取。
另外,在判断的时候还可以将式子两边乘方变为整数与 2 2 2 的次幂之间的比较,以提高精度。
参考代码:
#include <cstdio> #include <vector> #include <queue> #include <cmath> typedef long long ll; const ll INF=1e18; const int MAXN=1e5+10; int n,m; struct qnode{ int v; ll c; qnode(int v=0,ll c=0):v(v),c(c){} bool operator<(const qnode &oth)const{ return c>oth.c; } }; struct Edge{ int v,a,b; }; std::vector<Edge> G[MAXN]; ll dist[MAXN]; bool check(ll c,int a,int b){ return (1+a/c)>=((ll)1<<b); } std::priority_queue<qnode> pq; void dijkstra(){ dist[1]=1; pq.push(qnode(1,1)); qnode tmp; while (!pq.empty()){ tmp=pq.top();pq.pop(); int u=tmp.v; ll c=tmp.c; if (dist[u]<c) continue; for (int i=0;i<G[u].size();++i){ int v=G[u][i].v; int cost=G[u][i].a; int b=G[u][i].b; if (check(c,cost,b)&&dist[v]>c+cost){ dist[v]=c+cost; pq.push(qnode(v,dist[v])); } } } } void init(){ while (!pq.empty()) pq.pop(); for (int i=1;i<=n;++i) G[i].clear(); for (int i=1;i<=n;++i) dist[i]=INF; } int main(){ int t; scanf("%d",&t); while (t--){ scanf("%d%d",&n,&m); init(); for (int i=0;i<m;++i){ int u,v,a,b; scanf("%d%d%d%d",&u,&v,&a,&b); G[u].push_back((Edge){v,a,b}); } dijkstra(); ll res=dist[n]; if (res==INF) res=-1; else res=floor(log2(res)); printf("%lld\n",res); } return 0; }
题意:
给定两组数,求分别的最小值。
解法:
签到题,
O
(
n
)
O(n)
O(n) 算法求最值即可。
参考代码:
#include <cstdio> const int INF=0x3f3f3f3f; int main(){ int t; scanf("%d",&t); for (int x=1;x<=t;++x){ int n,m; scanf("%d%d",&n,&m); int y=INF,z=INF; for (int i=0;i<n;++i){ int a; scanf("%d",&a); if (a<y) y=a; } for (int i=0;i<m;++i){ int b; scanf("%d",&b); if (b<z) z=b; } printf("Problem %d:\n",x+1000); printf("Shortest judge solution: %d bytes.\n",y); if (z!=INF) printf("Shortest team solution: %d bytes.\n",z); else printf("Shortest team solution: N/A bytes.\n"); } return 0; }
题意:
给定一个字符串,请你比较该字符串每个相邻后缀的字典序大小。
题解见队友博客,点击查看。
题意:
给定参赛选手的测评信息,请你按照一定要求做成直播面板。
解法:
格式化输出问题,照做即可。
参考代码:
#include <cstdio> char s[20],t[20]; int main(){ int T; scanf("%d",&T); while (T--){ int rank,prob; scanf("%d %s %d %s",&rank,s,&prob,t); printf("%3d|%-16s|%d|[",rank,s,prob); if (t[0]=='F') printf(" AC* "); else if(t[0]=='R'&&t[1]=='u'){ int p; scanf("%d",&p); for (int i=0;i<p;i++) printf("X"); for (int i=p;i<10;i++) printf(" "); } else printf(" %-3s ",t); puts("]"); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。