[CSP-J 2024] 扑克牌 题解
2024-12-29 19:45:09
发布于:浙江
45阅读
0回复
0点赞
题目大意
给定一堆可能重复的扑克牌花色,求出其中还需要多少不同花色的扑克牌才能凑齐一整套花色完整的扑克牌。
题目难度
acgo 官网评分:普及-
; 个人评分:入门
部分分解法(不过这题应该不需要)
分解法:
由题目可得一副完整的扑克牌必须有 种花色,而特殊性质 满足了输入的牌花色两两不同,直接相减即可 ,非常适合那些只学了一两节C++就混进来的那种人 。
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
cout<<52-n;
return 0;
}
特殊性质 的解法:
特殊性质 满足所有牌按照点数从小到大依次输入,所以花色重复的牌会被排到一起,这样的特性适合用来去除重复项并统计。
#include<bits/stdc++.h>
using namespace std;
int n,cnt;
string a[52];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
if(a[i]!=a[i-1])cnt++;
}
cout<<52-cnt;
return 0;
}
本来想着应该只有 分的,结果直接得了 分,给我整懵了,但也说明了这题数据水。
正解
(终于能讲正解了)
解法一:
既然很多数据都不会按照顺序输入,那么我们可以在输入数据后对字符串数组进行排序,这样就会变成特殊性质 的情况了,剩下的就是套用特殊性质 的代码就行了。
#include<bits/stdc++.h>
using namespace std;
int n,cnt;
string a[52];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
if(a[i]!=a[i-1])cnt++;
}
cout<<52-cnt;
return 0;
}
当然,C++ 的 STL 函数模板中还有一个 unique
,可以达到类似效果。
#include<bits/stdc++.h>
using namespace std;
int n;
string a[52];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
int ans=(unique(a+1,a+1+n)-(a+1));
cout<<52-ans;
return 0;
}
解法二:
STL 数据结构中的 set
具有自动去重和排序的功能,对于这题来说可谓是专业对口。
#include<bits/stdc++.h>
using namespace std;
int n;
set<string>se;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
string s;
cin>>s;
se.emplace(s);
}
cout<<52-se.size();
return 0;
}
解法三:
STL 数据结构中的 map
和 unordered_map
可以利用哈希表的特性去重,也可以达到类似效果。
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,bool>m;
int n;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
while(n--){
string s;
cin>>s;
m[s]=1;
}
cout<<52-m.size();
return 0;
}
这里空空如也
有帮助,赞一个