我是靠谱客的博主 难过豌豆,这篇文章主要介绍[暴力枚举] CF118C Fancy Number,现在分享给大家,希望可以做个参考。

题目传送门

思路

暴力枚举

这个题目的核心思想其实就是暴力枚举,并且这个题细节特别多,要特别注意。我整整调了1个小时

就是枚举一边 0 0 0 9 9 9,并求出使得车牌号码中有 k k k 个枚举的数的代价是多少,如果这个代价小于以前枚举出来的最小代价,则这个代价就成为最小代价,并将方案记录下来。 如过以前的最小代价等于当前的代价,则就要注意一下字典序。

详情见代码。

代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int n,k; int a[15],q[100005],ans=0x3f3f3f3f,now[100005],now2[100005]; int flg;//flg来标记最后的答案是由1~9里面的那一个数字产生的 int cnt[100005];//标记要改变成flg的数 struct node { int id,num,w,pqr; bool operator <(const node &n)const//特别注意一下这里的排序规则(注意字典序)。 { if(pqr<=w&&pqr<=n.w) return num<n.num||(num==n.num&&id<n.id); else if(pqr>=w&&pqr>=n.w) return num<n.num||(num==n.num&&id>n.id); else return num<n.num||(num==n.num&&w>n.w); } }arr[100005]; char p[100005]; int main() { //输入 cin>>n>>k; for(int i=1;i<=n;++i) { cin>>p[i]; q[i]=p[i]-'0'; a[q[i]]++;//桶来标记1~9之间共有多少个数字 } for(int i=0;i<=9;++i) { if(a[i]>=k)//如果不用改变数字就可以完成了 { cout<<0<<endl; for(int i=1;i<=n;++i) cout<<q[i]; return 0; } for(int j=1;j<=n;++j) { arr[j].id=j;//id表示是这个车牌号的第几个 arr[j].w=q[j];//表示车牌号上的数值 arr[j].num=abs(q[j]-i);//表示替换这个数字为i需要多少代价 arr[j].pqr=i;//记录最后要改变成什么 } sort(arr+1,arr+n+1);//通过排序规则进行排序 int bj=0;//来改变为车牌号有k个i的最小代价 for(int j=1;j<=k;++j) { bj+=arr[j].num; } if(ans>bj)//如果以前的最小代价比当前最小代价大 { ans=bj;//改变最小代价 flg=i;//最后的答案是由车牌号变成k个i产生的 memset(cnt,0,sizeof(cnt)); for(int j=1;j<=k;++j) { cnt[j]=arr[j].id;//记录究竟要改变那些下标上的数字为i } } else if(ans==bj)//如果以前的最小代价等于当前最小待机,则我们要注意字典序 { bool kkk=0;//标记 for(int j=1;j<=n;++j) { //用一个临时调用的数字来进行操作 now[j]=q[j]; now2[j]=q[j]; } for(int j=1;j<=k;++j) { //通过储存下来的要改变的方案进行改变 now[arr[j].id]=i; now2[cnt[j]]=flg; } for(int j=1;j<=n;++j) { if(now[j]<now2[j])//如果用i产生的最小代价的字典序更小 { kkk=1;//标记 break;//跳出循环 } else if(now[j]>now2[j])//如果用flg产生的最小代价的字典序更小 { break;//跳出循环,无需标记 } } if(kkk==1)//如果用i产生的最小代价的字典序更小 { flg=i;//flg进行替换 memset(cnt,0,sizeof(cnt)); for(int j=1;j<=k;++j) { cnt[j]=arr[j].id;//储存那些下标需要替换 } } } } for(int i=1;i<=k;++i) q[cnt[i]]=flg;//进行改变 //输出 cout<<ans<<endl; for(int i=1;i<=n;++i) cout<<q[i]; }

最后

以上就是难过豌豆最近收集整理的关于[暴力枚举] CF118C Fancy Number的全部内容,更多相关[暴力枚举]内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部