[2023-10-27]2023 CSP_J(复赛)题解
2023 CSP_J(复赛)题解
T1 P9748 [CSP-J 2023] 小苹果【民间数据】
正文
题目不难,但不能用数组硬模拟。
思路:一层循环,每一次判断是否可以取到最后一个,并计数。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n;
scanf("%lld",&n);
long long frt=n;
long long cnt=0;
long long ans=-1;
while(frt>1){
cnt++;
if(frt%3==1 && ans==-1){//取到最后一个
ans=cnt;
}
frt-=(frt-1)/3+1;//减少总数量
if(frt==1){//如果只剩一个数
cnt++;//取最后一个数
if(ans==-1)ans=cnt;//如果这个数是最后一个
break;
}
}
printf("%lld %lld",cnt,ans);
return 0;
}
T2 P9749 [CSP-J 2023] 公路【民间数据】
正文
思路:贪心思想。
因为油箱容量是无限的,为了省钱,我们在每次需要加油的时候一定去最便宜的加油站,且这个加油站是已经经过了的。
坑:一定要开long long!!在这上面浪费了半个小时....
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long n,d;
long long v[1000005];
long long a[1000005];
long long minprice[1000005]={9999999};//表示当前位置及之前最便宜的油价
long long shengKM=0;
long long pay=0;
int main(){
scanf("%lld%lld",&n,&d);
for(long long i=1;i<=n-1;i++){
scanf("%lld",&v[i]);
}
for(long long i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]<minprice[i-1]){//找最便宜的油价
minprice[i]=a[i];
}
else{
minprice[i]=minprice[i-1];
}
}
for(long long i=1;i<=n-1;i++){
if(shengKM>=v[i]){//如果剩下的油已经够跑了
shengKM-=v[i];
continue;
}
long long needKM=v[i]-shengKM;//除去剩下的,还需要跑的公里数
long long jia=needKM%d==0?needKM/d:needKM/d+1;//需要加的油
pay+=jia*minprice[i];//需要支付的钱
shengKM=jia*d-needKM;//剩余的油
}
printf("%lld",pay);
return 0;
}
T3 P9750 [CSP-J 2023] 一元二次方程【民间数据】
正文
思路:三个参数带进Δ,模拟就行。
代码如下:
#include <bits/stdc++.h>
using namespace std;
void print(int fz, int fm) {
int g = abs(__gcd(fz, fm));
fz /= g, fm /= g;
if (fm == 1)
printf("%d", fz);
else
printf("%d/%d", fz, fm);
}
int main() {
int _;
scanf("%d%*d", &_);
while (_--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int d = b * b - 4 * a * c;
if (d < 0)
printf("NO");
else {
int x = 0;
for (int i = 1; i * i <= d; i++) {
if (d % (i * i) == 0) x = i;
}
if (x * x == d) {
int fz, fm;
if (a > 0)
fz = -b + x, fm = 2 * a;
else
fz = b + x, fm = -2 * a;
print(fz, fm);
} else {
int fz, fm;
if (a > 0)
fz = -b, fm = 2 * a;
else
fz = b, fm = -2 * a;
if (fz != 0) {
print(fz, fm);
putchar('+');
}
int r = d / (x * x);
if (a > 0)
fz = x, fm = 2 * a;
else
fz = x, fm = -2 * a;
int g = __gcd(fz, fm);
fz /= g, fm /= g;
if (fm == 1) {
if (fz == 1)
printf("sqrt(%d)", r);
else
printf("%d*sqrt(%d)", fz, r);
} else if (fz == 1) {
printf("sqrt(%d)/%d", r, fm);
} else {
printf("%d*sqrt(%d)/%d", fz, r, fm);
}
}
}
printf("\n");
}
return 0;
}
T4 P9751 [CSP-J 2023] 旅游巴士【民间数据】
正文
思路:Dijkstra算法。类似bfs。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 10005;
vector<pair<int, int>> G[N];
int d[N][105];
int vis[N][105];
struct Node {
int u, i, d;
bool operator<(const Node &rhs) const {
return d > rhs.d;
}
};
int main() {
int n, m, kk;
scanf("%d%d%d", &n, &m, &kk);
while (m--) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u].push_back({v, w});
}
memset(d, 0x3f, sizeof d);
priority_queue<Node> q;
q.push({1, 0, d[1][0] = 0});
while (q.size()) {
int u = q.top().u, i = q.top().i;
q.pop();
if (vis[u][i]) continue;
vis[u][i] = 1;
for (auto [v, w] : G[u]) {
int t = d[u][i], j = (i + 1) % kk;
if (t < w) t += (w - t + kk - 1) / kk * kk;
if (d[v][j] > t + 1) q.push({v, j, d[v][j] = t + 1});
}
}
if (d[n][0] == INF) d[n][0] = -1;
printf("%d\n", d[n][0]);
return 0;
}

浙公网安备 33010602011771号