Loading

[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;
}
posted @ 2024-09-06 23:01  TommyJin  阅读(52)  评论(0)    收藏  举报