Codeforces 915 C. Permute Digits (dfs)

题目链接:Permute Digits

题意:

  给出了两个数字a,b(<=1e18),保证a,b都不带前缀0。用a的字符重组一个数字使这个值最大且小于b。(保证这个值存在)

题解:

  这题遇到了不止一遍了,但是每次都会写错~所以感觉很有必要写下来。看到这题,我的第一想法是贪心每次都取最大的。但是这样其实存在很大的漏洞,因为字符个数是有限的如果小的数被取完了大的数填充进去也不符合条件。这题要按DFS的思路去做才行。这里给出按贪心的做法的一组错误数据。

a: 123456789123456789

b: 276193619183618162

my_output: 276193618987554432

answer: 276193618987554432

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_N = 1e3+9;
 4 char vec[MAX_N];
 5 char s[MAX_N];
 6 int res[MAX_N];
 7 char out[MAX_N];
 8 int point;
 9 void dfs(int pos,int flag,int len)
10 {
11     if(pos == len)
12     {
13         out[len] = '\0';
14         printf("%s\n",out);
15         exit(0);
16     }
17     //cout<<"...."<<endl;
18     int t = pos+point;
19     if(flag)
20     {
21         bool f = true;
22         for(int j=9; j>=0; j--)
23         {
24             if(res[j])
25             {
26                 out[pos] = j+'0';
27                 res[j]--;
28                 dfs(pos+1,flag,len);
29                 res[j]++;
30             }
31         }
32         if(f) return;
33     }
34     else
35     {
36         bool f = true;
37         for(int j=s[t]-'0'; j>=0; j--)
38         {
39             if(res[j])
40             {
41                 //cout<<"......"<<j<<"..."<<s[t]<<endl;
42                 out[pos] = j+'0';
43                 res[j]--;
44                 if(j==s[t]-'0') dfs(pos+1,0,len);
45                 else dfs(pos+1,1,len);
46                 res[j]++;
47             }
48         }
49         if(f) return;
50     }
51 
52 
53 }
54 int main()
55 {
56     int N,M,T;
57     memset(res,0,sizeof(res));
58     scanf("%s",vec);
59     scanf("%s",s);
60     int len = strlen(vec);
61     for(int i=0; i<len; i++) res[vec[i]-'0']++;
62     int l = strlen(s);
63     point = l - len;
64     if(point > 0) dfs(0,1,len);
65     else dfs(0,0,len);
66     return 0;
67 }

 

转载于:https://www.cnblogs.com/doggod/p/8417149.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值