C++课后习题训练记录Day147
1.练习项目 问题描述有 n 个传送阵编号为 1∼n每个传送阵使用若干块 星石 作为能源。星石 是一种很神奇的物质一块 星石 的能量值等于它的价值。同时星石放在一起会激发更强大的能量例如有 3 块 星石 的能量值分别为 2,3,4则它们放在一起可以提供的能量为 2×3×424需要消耗的价值为 2349。现在每个传送阵都有一个能量值 x f(x) 是构成 x 的星石最小价值之和对 n 取模加一换句话说便是 f(x)(sum modn)1sum 是构成 x 的星石最小价值之和。例如x9,n997,f(x)(33)mod99717。而两个传送阵可以相互传送的规则如下如果两个传送阵的 f(x) 相等则两个传送阵可以相互传送。例如 n6,x8,x9 便可以相互传送。能量值为 x 的传送阵可以和编号为 f(x) 的传送阵相互传送。例如 n6,a[4]9a[4] 是假设 4 号传送阵能量为 9所以 4 号传送阵可以和 7 号传送阵能相互传送。因为 4 号传送阵的能量值为 9f(x)(33modn)17。给定每个传送阵都有的能量值 x你需要求出从编号 a 到编号 b 的最少传送次数若不能到达请输出 -1。输入格式第 1 行输入 3 个正整数表示 n,a,b含义为传送阵的数量起点编号与终点编号。第 2 行输入 n 个正整数 x表示每个传送阵的能量值。输出格式输出 1 行表示 a 到 b 的最少传送次数若不能从 a 传送到 b 则输出 -1。2.选择课程在蓝桥云课中选择题库选择题号6281并开始练习。3.开始练习1源码 #includebits/stdc.husing namespace std;using ll long long;const int N 1e510;vectorintprimes;ll f[N];void euler(int n){bitset(int)1e810vis;vis[0]vis[1]true;for(int i2;in;i){if(!vis[i])primes.push_back(i);for(int j0;jprimes.size()i*primes[j]n;j){vis[i*primes[j]]true;if(i%primes[j]0)break;}}}ll F(ll x,int n){ll res0;for(int i0;iprimes.size()primes[i]x/primes[i];i){ll prime primes[i];while(x%prime0)resprime,x/prime;}if(x1)resx;return res%n1;}struct Edge{int x,w;bool operator (const Edge u)const{if(w ^ u.w)return wu.w;return xu.x;}};vectorEdgeg[2*N];const ll inf2e18;ll d[2*N];void dijkstra(int st,int n){for(int i1;i2*n;i)d[i]inf;bitset2*Nvis;priority_queueEdgepq;pq.push({st,d[st]0});while(pq.size()){int xpq.top().x;pq.pop();if(vis[x])continue;vis[x]true;for(const auto t:g[x]){int yt.x,wt.w;if(d[y]d[x]w){pq.push({y,d[y]d[x]w});}}}}int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n,a,b;cinnab;euler(1e8);for(int i1;in;i){ll x;cinx;f[i]F(x,n);g[i].push_back({f[i],1});g[f[i]].push_back({i,1});}//虚拟源点for(int i1;in;i){g[i].push_back({nf[i],0});g[nf[i]].push_back({i,1});}dijkstra(a,n);cout(d[b]inf?-1:d[b])\n;return 0;}2检验结果对此代码进行检验检验后无报错提交此代码判题结果为正确100分。3练习心得注意每段代码末尾的分号是否存在 如不存在则需即使补充输入法 是否切换 为英语模式语法是否错误。