URAL 1658. Sum of Digits(DP)

本文分享了一个关于URAL竞赛中一道难题的解决方案,通过SPFA算法实现了最短路径的求解并输出路径。作者最初尝试了记录每条路径的方法但遭遇失败,最终采用倒序记录最小值的方式成功解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

隔了一年零三个月,重新刷URAL,这题挺麻烦的输出路径。输出路径挺扯的,乱写了写乱改改就A了。。。我本来想用很靠谱,记录每一条路径的,然后输出最小的,结果Tle,然后我使劲水水又过了一组,发现别人的题解。。直接来了一次 就过了。。我乱搞了搞,倒着记录最小的,然后倒着输出,就过了。。。

 1 #include <cstring>
 2 #include <cstdio>
 3 #include <string>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 using namespace std;
 9 #define INF 10000000
10 int dp[901][8101];
11 int pre[901][8101];
12 int s[1010];
13 struct node
14 {
15     int a,b;
16 };
17 void spfa()
18 {
19     int i,a,b;
20     queue<node> que;
21     node temp,u,v;
22     for(i = 1; i < 10; i ++)
23     {
24         temp.a = i;
25         temp.b = i*i;
26         dp[i][i*i] = 1;
27         pre[i][i*i] = i;
28         que.push(temp);
29     }
30     while(!que.empty())
31     {
32         u = que.front();
33         a = u.a;
34         b = u.b;
35         que.pop();
36         if(a > 900) continue;
37         if(b > 8100) continue;
38         for(i = 1; i < 10; i ++)
39         {
40             v.a = i+a;
41             v.b = i*i+b;
42             if(i + a > 900) continue;
43             if(i*i + b > 8100) continue;
44             if(dp[v.a][v.b] > dp[u.a][u.b] + 1)
45             {
46                 pre[v.a][v.b] = i;
47                 dp[v.a][v.b] = dp[u.a][u.b] + 1;
48                 que.push(v);
49             }
50         }
51     }
52     return ;
53 }
54 
55 int main()
56 {
57     int t,n,m,i,j;
58     int top;
59     for(i = 1; i <= 900; i ++)
60     {
61         for(j = 1; j <= 8100; j ++)
62         {
63             dp[i][j] = INF;
64             pre[i][j] = INF;
65         }
66     }
67     spfa();
68     scanf("%d",&t);
69     top = 0;
70     while(t--)
71     {
72         scanf("%d%d",&n,&m);
73         if(n > 900||m > 8100)
74         {
75             printf("No solution\n");
76             continue;
77         }
78         else if(dp[n][m] > 100)
79         {
80             printf("No solution\n");
81             continue;
82         }
83         int top = 0;
84         while(n&&m)
85         {
86             i = pre[n][m];
87             s[top++] = i;
88             n = n - i;
89             m = m - i*i;
90         }
91         for(i = top-1;i >= 0;i --)
92         printf("%d",s[i]);
93         printf("\n");
94     }
95     return 0;
96 }

 

转载于:https://www.cnblogs.com/naix-x/p/3297558.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值