Ural 1658 Sum of Digits

来源:互联网 发布:青铜器铭文翻译软件 编辑:程序博客网 时间:2024/03/29 01:05

PRO IS HERE


0<s1<901 ,0<s2<8100

我用队列直接枚举(s1,s2) 是否可行。

dp[s1][s2] 表示达到(s1,s2) 加的数,就是:

s1  =  S1 - dp[s1][s2] ,s2 = S2 - dp[s1][s2]^2

No solution 打成 NO solution WA 了n次。。。


#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<set>#include<queue>#include<map>#include<iostream>using namespace std;#define PB push_back#define INS insert#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)#define nMax 201#define bug puts("Fuck");#define LL long long#define mp make_pair#define F first#define S second#define iter set<pair<int,int> >::iteratorint dp[901][8101],dist[901][8101];queue<pair<int,int> > que;void init(){FOR(i,0,900)FOR(j,0,8100) dp[i][j]=-1;dp[0][0]=0;dist[0][0]=0;que.push(mp(0,0));while(!que.empty()){        pair<int,int> u = que.front();que.pop();        if(dist[u.F][u.S]>=100) break;        for(int j=1;j<10;j++) if(u.F+j<901 && u.S+j*j<8101 && dp[u.F+j][u.S+j*j]==-1){            dp[u.F+j][u.S+j*j]=j;            dist[u.F+j][u.S+j*j]=dist[u.F][u.S]+1;            que.push(mp(u.F+j,u.S+j*j));        }}//FOR(i,1,900) FOR(j,1,8100) if(dp[i][j]!=-1) printf("dp[%d][%d]=%d\n",i,j,dp[i][j]);/*for(int i = 1;i<=100;i++) {for(int s=1;s<901;s++) {for(int t=1;t<8101;t++)if(dp[s][t]==-1){for(int j=1;j<10;j++) if(s>=j && t-j*j>=0 && dp[s-j][t-j*j]!=-1){dp[s][t]=j;break;}}}}*/}void out(int x,int y){if(x==0 && y==0) return ;if(dp[x][y]==-1) {        printf("No solution");        return ;}out(x-dp[x][y],y-dp[x][y]*dp[x][y]);printf("%d",dp[x][y]);return ;}int main(){    //freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);init();    int t;scanf("%d",&t);int s1,s2;while(t--){scanf("%d%d",&s1,&s2);if(s1>900 || s2 > 8100) {            puts("No solution");            continue;        }out(s1,s2);puts("");}return 0;}


原创粉丝点击