1.小苹果(apple)
题目描述
小 Y 的桌子上放着 nn 个苹果从左到右排成一列,编号为从 11 到 nn。
小苞是小 Y 的好朋友,每天她都会从中拿走一些苹果。
每天在拿的时候,小苞都是从左侧第 11 个苹果开始、每隔 22 个苹果拿走 11 个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一列。
小苞想知道,多少天能拿完所有的苹果,而编号为 nn 的苹果是在第几天被拿走的?
输入格式
输入的第一行包含一个正整数 nn,表示苹果的总数。
输出格式
输出一行包含两个正整数,两个整数之间由一个空格隔开,分别表示小苞拿走所有苹果所需的天数以及拿走编号为 nn 的苹果是在第几天。
输入输出样例
输入 #1复制
8
输出 #1复制
5 5
说明/提示
【样例 11 解释】
小苞的桌上一共放了 88 个苹果。
小苞第一天拿走了编号为 11、44、77 的苹果。
小苞第二天拿走了编号为 22、66 的苹果。
小苞第三天拿走了编号为 33 的苹果。
小苞第四天拿走了编号为 55 的苹果。
小苞第五天拿走了编号为 88 的苹果。
【样例 22】
见选手目录下的 apple/apple2.in 与 apple/apple2.ans。
【数据范围】
对于所有测试数据有:1\leq n\leq 10^91≤n≤109。
测试点 | n\leqn≤ | 特殊性质 |
---|---|---|
1\sim 21∼2 | 1010 | 无 |
3\sim 53∼5 | 10^3103 | 无 |
6\sim 76∼7 | 10^6106 | 有 |
8\sim 98∼9 | 10^6106 | 无 |
1010 | 10^9109 | 无 |
特殊性质:小苞第一天就取走编号为 nn 的苹果。
附件下载
apple.zip418B
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
int k=n,d=0,ans=0;
while(k>0) {
if(k%3==1&&ans==0) ans=d+1;
int t=(k-1)/3+1;
k=k-t;
d++;
}
cout<<d<<" "<<ans;
return 0;
}
2.公路(road)
题目描述
小苞准备开着车沿着公路自驾。
公路上一共有 nn 个站点,编号为从 11 到 nn。其中站点 ii 与站点 i + 1i+1 的距离为 v_ivi 公里。
公路上每个站点都可以加油,编号为 ii 的站点一升油的价格为 a_iai 元,且每个站点只出售整数升的油。
小苞想从站点 11 开车到站点 nn,一开始小苞在站点 11 且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进 dd 公里。问小苞从站点 11 开到站点 nn,至少要花多少钱加油?
输入格式
输入的第一行包含两个正整数 nn 和 dd,分别表示公路上站点的数量和车每升油可以前进的距离。
输入的第二行包含 n - 1n−1 个正整数 v_1, v_2\dots v_{n-1}v1,v2…vn−1,分别表示站点间的距离。
输入的第三行包含 nn 个正整数 a_1, a_2 \dots a_na1,a2…an,分别表示在不同站点加油的价格。
输出格式
输出一行,仅包含一个正整数,表示从站点 11 开到站点 nn,小苞至少要花多少钱加油。
输入输出样例
输入 #1复制
5 4 10 10 10 10 9 8 9 6 5
输出 #1复制
79
说明/提示
【样例 1 解释】
最优方案下:小苞在站点 11 买了 33 升油,在站点 22 购买了 55 升油,在站点 44 购买了 22 升油。
【样例 2】
见选手目录下的 road/road2.in 与 road/road2.ans。
【数据范围】
对于所有测试数据保证:1 \leq n \leq 10^51≤n≤105,1 \leq d \leq 10^51≤d≤105,1 \leq v_i \leq 10^51≤vi≤105,1 \leq a_i \leq 10^51≤ai≤105。
测试点 | n \leqn≤ | 特殊性质 |
---|---|---|
1\sim 51∼5 | 88 | 无 |
6\sim 106∼10 | 10^3103 | 无 |
11\sim 1311∼13 | 10^5105 | A |
14\sim 1614∼16 | 10^5105 | B |
17\sim 2017∼20 | 10^5105 | 无 |
- 特殊性质 A:站点 11 的油价最低。
- 特殊性质 B:对于所有 1 \leq i < n1≤i<n,v_ivi 为 dd 的倍数。
附件下载
road.zip3.09KB
AC代码:
#include <bits/stdc++.h>
using namespace std;
int n, d, k=0, minn=1e9;
long long cost = 0;
int a[100005] = {0};
int v[100005] = {0};
int main()
{
cin >> n >> d;
for (int i=1; i<n; i++) {
cin >> v[i];
}
for (int i=1; i<=n; i++) {
cin >> a[i];
}
for(int i=1;i<n;i++){
minn=min(minn,a[i]);
if(k>=v[i]){
k=k-v[i];
continue;
}
cost += 1ll * ceil(1.0 *(v[i]-k)/d) * minn;
k = 1ll * ceil(1.0 *(v[i]-k)/d)*d - (v[i]-k);
}
cout << cost<<"\n";
return 0;
}
3.一元二次方程(uqe)
题目背景
众所周知,对一元二次方程 ax ^ 2 + bx + c = 0, (a \neq 0)ax2+bx+c=0,(a=0),可以用以下方式求实数解:
- 计算 \Delta = b ^ 2 - 4acΔ=b2−4ac,则:
- 若 \Delta < 0Δ<0,则该一元二次方程无实数解。
- 否则 \Delta \geq 0Δ≥0,此时该一元二次方程有两个实数解 x _ {1, 2} = \frac{-b \pm \sqrt \Delta}{2a}x1,2=2a−b±Δ。
例如:
- x ^ 2 + x + 1 = 0x2+x+1=0 无实数解,因为 \Delta = 1 ^ 2 - 4 \times 1 \times 1 = -3 < 0Δ=12−4×1×1=−3<0。
- x ^ 2 - 2x + 1 = 0x2−2x+1=0 有两相等实数解 x _ {1, 2} = 1x1,2=1。
- x ^ 2 - 3x + 2 = 0x2−3x+2=0 有两互异实数解 x _ 1 = 1, x _ 2 = 2x1=1,x2=2。
在题面描述中 aa 和 bb 的最大公因数使用 \gcd(a, b)gcd(a,b) 表示。例如 1212 和 1818 的最大公因数是 66,即 \gcd(12, 18) = 6gcd(12,18)=6。
题目描述
现在给定一个一元二次方程的系数 a, b, ca,b,c,其中 a, b, ca,b,c 均为整数且 a \neq 0a=0。你需要判断一元二次方程 a x ^ 2 + bx + c = 0ax2+bx+c=0 是否有实数解,并按要求的格式输出。
在本题中输出有理数 vv 时须遵循以下规则:
-
由有理数的定义,存在唯一的两个整数 pp 和 qq,满足 q > 0q>0,\gcd(p, q) = 1gcd(p,q)=1 且 v = \frac pqv=qp。
-
若 q = 1q=1,则输出
{p}
,否则输出{p}/{q}
,其中{n}
代表整数 nn 的值; -
例如:
- 当 v = -0.5v=−0.5 时,pp 和 qq 的值分别为 -1−1 和 22,则应输出
-1/2
; - 当 v = 0v=0 时,pp 和 qq 的值分别为 00 和 11,则应输出
0
。
- 当 v = -0.5v=−0.5 时,pp 和 qq 的值分别为 -1−1 和 22,则应输出
对于方程的求解,分两种情况讨论:
-
若 \Delta = b ^ 2 - 4ac < 0Δ=b2−4ac<0,则表明方程无实数解,此时你应当输出
NO
; -
否则 \Delta \geq 0Δ≥0,此时方程有两解(可能相等),记其中较大者为 xx,则:
-
若 xx 为有理数,则按有理数的格式输出 xx。
-
否则根据上文公式,xx 可以被唯一表示为 x = q _ 1 + q _ 2 \sqrt rx=q1+q2r 的形式,其中:
- q _ 1, q _ 2q1,q2 为有理数,且 q _ 2 > 0q2>0;
- rr 为正整数且 r > 1r>1,且不存在正整数 d > 1d>1 使 d ^ 2 \mid rd2∣r(即 rr 不应是 d ^ 2d2 的倍数);
此时:
- 若 q _ 1 \neq 0q1=0,则按有理数的格式输出 q _ 1q1,并再输出一个加号
+
; - 否则跳过这一步输出;
随后:
- 若 q _ 2 = 1q2=1,则输出
sqrt({r})
; - 否则若 q _ 2q2 为整数,则输出
{q2}*sqrt({r})
; - 否则若 q _ 3 = \frac 1{q _ 2}q3=q21 为整数,则输出
sqrt({r})/{q3}
; - 否则可以证明存在唯一整数 c, dc,d 满足 c, d > 1, \gcd(c, d) = 1c,d>1,gcd(c,d)=1 且 q _ 2 = \frac cdq2=dc,此时输出
{c}*sqrt({r})/{d}
;
上述表示中
{n}
代表整数{n}
的值,详见样例。如果方程有实数解,则按要求的格式输出两个实数解中的较大者。否则若方程没有实数解,则输出
NO
。 -
输入格式
输入的第一行包含两个正整数 T, MT,M,分别表示方程数和系数的绝对值上限。
接下来 TT 行,每行包含三个整数 a, b, ca,b,c。
输出格式
输出 TT 行,每行包含一个字符串,表示对应询问的答案,格式如题面所述。
每行输出的字符串中间不应包含任何空格。
输入输出样例
输入 #1复制
9 1000 1 -1 0 -1 -1 -1 1 -2 1 1 5 4 4 4 1 1 0 -432 1 -3 1 2 -4 1 1 7 1
输出 #1复制
1 NO 1 -1 -1/2 12*sqrt(3) 3/2+sqrt(5)/2 1+sqrt(2)/2 -7/2+3*sqrt(5)/2
说明/提示
【样例 #2】
见附件中的 uqe/uqe2.in
与 uqe/uqe2.ans
。
【数据范围】
对于所有数据有:1 \leq T \leq 50001≤T≤5000,1 \leq M \leq 10 ^ 31≤M≤103,|a|,|b|,|c| \leq M∣a∣,∣b∣,∣c∣≤M,a \neq 0a=0。
测试点编号 | M \leqM≤ | 特殊性质 A | 特殊性质 B | 特殊性质 C |
---|---|---|---|---|
11 | 11 | 是 | 是 | 是 |
22 | 2020 | 否 | 否 | 否 |
33 | 10 ^ 3103 | 是 | 否 | 是 |
44 | 10 ^ 3103 | 是 | 否 | 否 |
55 | 10 ^ 3103 | 否 | 是 | 是 |
66 | 10 ^ 3103 | 否 | 是 | 否 |
7, 87,8 | 10 ^ 3103 | 否 | 否 | 是 |
9, 109,10 | 10 ^ 3103 | 否 | 否 | 否 |
其中:
- 特殊性质 A:保证 b = 0b=0;
- 特殊性质 B:保证 c = 0c=0;
- 特殊性质 C:如果方程有解,那么方程的两个解都是整数。
附件下载
uqe.zip29.51KB
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,m,a,b,c;
int gcd(int p,int q){
int u;
while(q!=0){
u=p%q;
p=q;
q=u;
}
return p;
}
void work1(int p,int q){
if(p*q<0) cout<<'-';
if(p<0) p=0-p;
if(q<0) q=0-q;
int g=gcd(p,q);
if(g==q) cout<<p/g;
else cout<<p/g<<'/'<<q/g;
return;
}
void work2(int p,int q){
if(p<0) p=-p;
if(q<0) q=-q;
int u=1;
for(int i=sqrt(p); i>=2; i--) {
if(p%(i*i)==0){
p=p/(i*i);
u=u*i;
break;
}
}
int g=gcd(u,q);
u=u/g;
q=q/g;
if(u!=1) cout<<u<<"*";
if(p!=1) cout<<"sqrt("<<p<<")";
if(q!=1) cout<<"/"<<q;
}
int main(){
// freopen("uqe2.in","r",stdin);
// freopen("uqe2.ans","w",stdout);
cin>>t>>m;
while(t--) {
cin>>a>>b>>c;
int d=b*b-4*a*c;
if(d<0){
cout<<"NO";
}else{
int q=sqrt(d);
if(q*q==d) {
double ans1=1.0*(-b+q)/(2*a);
double ans2=1.0*(-b-q)/(2*a);
if(ans1>ans2) {
if(-b+q==0) cout<<0;
else work1(-b+q,2*a);
} else {
if(-b-q==0) cout<<0;
else work1(-b-q,2*a);
}
} else {
if(b!=0) work1(-b,2*a);
if(b!=0) cout<<"+";
work2(d,2*a);
}
}
cout<<"\n";
}
return 0;
}
4.旅游巴士(bus)
题目描述
小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。
旅游景点的地图共有 nn 处地点,在这些地点之间连有 mm 条道路。其中 11 号地点为景区入口,nn 号地点为景区出口。我们把一天当中景区开门营业的时间记为 00 时刻,则从 00 时刻起,每间隔 kk 单位时间便有一辆旅游巴士到达景区入口,同时有一辆旅游巴士从景区出口驶离景区。
所有道路均只能单向通行。对于每条道路,游客步行通过的用时均为恰好 11 单位时间。
小 Z 希望乘坐旅游巴士到达景区入口,并沿着自己选择的任意路径走到景区出口,再乘坐旅游巴士离开,这意味着他到达和离开景区的时间都必须是 kk 的非负整数倍。由于节假日客流众多,小 Z 在旅游巴士离开景区前只想一直沿着景区道路移动,而不想在任何地点(包括景区入口和出口)或者道路上停留。
出发前,小 Z 忽然得知:景区采取了限制客流的方法,对于每条道路均设置了一个 “开放时间”a _ iai,游客只有不早于 a _ iai 时刻才能通过这条道路。
请帮助小 Z 设计一个旅游方案,使得他乘坐旅游巴士离开景区的时间尽量地早。
输入格式
输入的第一行包含 3 个正整数 n, m, kn,m,k,表示旅游景点的地点数、道路数,以及旅游巴士的发车间隔。
输入的接下来 mm 行,每行包含 3 个非负整数 u _ i, v _ i, a_ iui,vi,ai,表示第 ii 条道路从地点 u _ iui 出发,到达地点 v _ ivi,道路的“开放时间”为 a _ iai。
输出格式
输出一行,仅包含一个整数,表示小 Z 最早乘坐旅游巴士离开景区的时刻。如果不存在符合要求的旅游方案,输出 -1
。
输入输出样例
输入 #1复制
5 5 3 1 2 0 2 5 1 1 3 0 3 4 3 4 5 1
输出 #1复制
6
说明/提示
【样例 #1 解释】
小 Z 可以在 33 时刻到达景区入口,沿 1 \to 3 \to 4 \to 51→3→4→5 的顺序走到景区出口,并在 66 时刻离开。
【样例 #2】
见附件中的 bus/bus2.in
与 bus/bus2.ans
。
【数据范围】
对于所有测试数据有:2 \leq n \leq 10 ^ 42≤n≤104,1 \leq m \leq 2 \times 10 ^ 41≤m≤2×104,1 \leq k \leq 1001≤k≤100,1 \leq u _ i, v _ i \leq n1≤ui,vi≤n,0 \leq a _ i \leq 10 ^ 60≤ai≤106。
测试点编号 | n \leqn≤ | m \leqm≤ | k \leqk≤ | 特殊性质 |
---|---|---|---|---|
1 \sim 21∼2 | 1010 | 1515 | 100100 | a _ i = 0ai=0 |
3 \sim 53∼5 | 1010 | 1515 | 100100 | 无 |
6 \sim 76∼7 | 10 ^ 4104 | 2 \times 10 ^ 42×104 | 11 | a _ i = 0ai=0 |
8 \sim 108∼10 | 10 ^ 4104 | 2 \times 10 ^ 42×104 | 11 | 无 |
11 \sim 1311∼13 | 10 ^ 4104 | 2 \times 10 ^ 42×104 | 100100 | a _ i = 0ai=0 |
14 \sim 1514∼15 | 10 ^ 4104 | 2 \times 10 ^ 42×104 | 100100 | u _ i \leq v _ iui≤vi |
16 \sim 2016∼20 | 10 ^ 4104 | 2 \times 10 ^ 42×104 | 100100 | 无 |
附件下载
bus.zip155.15KB
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=10010,M=20010,inf=0x3f3f3f3f;
int n,m,k;
int h[N],e[M],ne[M],w[M],idx=0;
int dis[N][105],path[N];
void add(int a,int b,int c) {
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
struct node {
int v,d;
} t;
struct cmp{
bool operator()(const node a,const node b) {
return a.d>b.d;
}
};
int dijkstra() {
memset(dis,0x3f,sizeof dis);
priority_queue<node,vector<node>,cmp> heap;
path[1]=0;
heap.push({1,0});
while(!heap.empty()) {
t=heap.top();
heap.pop();
if(dis[t.v][t.d%k]<t.d) continue;
for(int i=h[t.v]; i!=-1; i=ne[i]) {
int j=e[i];
int tt=t.d;
if(tt+1<w[i]) {
tt+=((w[i]-1-tt+k)/k*k);
}
if(tt+1<dis[j][(tt+1)%k]) {
dis[j][(tt+1)%k]=tt+1;
heap.push({j,dis[j][(tt+1)%k]});
}
}
}
if(dis[n][0]>=inf) return -1;
else return dis[n][0];
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
memset(h,-1,sizeof h);
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int u,v,a;
cin>>u>>v>>a;
add(u,v,a);
}
cout<<dijkstra();
return 0;
}
制作不易,希望点个关注~~~