3 条题解
-
1
如果要确定a在序列中出现的次数是否大于等于b,且b出现的次数大于等于a,可以创建一个数组来统计出现数字的次数,然后再对每一个数字的次数进行维护。
注意到数字a的出现的次数肯定在 [1,cnt[a]] 的范围内,那就可以确定可能的b肯定也在1到cnt[a]的范围内,因此对该区间内的数做一个判断,即判断区间内出现的数字的出现次数是否大于等于a即可。
#include <bits/stdc++.h> #define all(x) (x).begin(), (x).end() #define pb push_back #define pf push_front using namespace std; using ll = long long; using ull = unsigned long long; typedef pair<int, int> P; const int mod = 998244353; const int MOD = 1e9 + 7; void solve() { int n; cin >> n; vector<int> cnt(n + 1); // 统计读入的数的出现次数 for (int i = 1; i <= n; i++) { int ai; cin >> ai; cnt[ai]++; } int ans = 0; for (int i = 1; i <= n; i++) { if (!cnt[i]) continue; for (int j = 1; j <= cnt[i]; j++) { if (cnt[j] >= i) // 判断数字次数是否大于等于a ans++; } } cout << ans << endl; } int main() { ios::sync_with_stdio(false); cin.tie(0); int T = 1; // cin >> T; while (T--) { solve(); } return 0; } -
0
import java.util.ArrayList; import java.util.Scanner; public class Main {
public static void main(String[] args) { Scanner sc = new Scanner(System.in); //思路 int n=sc.nextInt(); int ans=0; int[]cnt=new int[200001];//计数 boolean[]vis=new boolean[200001];//判断是否读入,去重 ArrayList<Integer>list=new ArrayList<>();//存数 for(int i=0;i<n;i++) { int m=sc.nextInt(); cnt[m]++;//
if(!list.contains(m))list.add(m);太慢->visif(!vis[m]) { list.add(m);//没读入的话 vis[m]=true; } } for(int i=0;i<list.size();i++) {//一个数跟每个数配对// for(int j=0;j<list.size();j++) { // int a=list.get(i),b=list.get(j); // if(cnt[a]>=b&&cnt[b]>=a)ans++; // }超时
int a=list.get(i);//先枚举a for(int b=1;b<=cnt[a];b++) {//再枚举<=cnt[a]的b if(vis[b]&&cnt[b]>=a)ans++;//看是否有数,和满足另一个条件 } } System.out.println(ans); }}
-
0
#include<bits/stdc++.h> using namespace std; #define int long long /* 完美数队:a,b 如果a出现次数>=b 且b出现次数>=a 既可以 //思路:一步一步来:暴力到优化 次数:想到1排序+map 2去重!!!!!! //优化思路: 1去重 将n转化为sum 已经小很多了 2 a,b<=sart(n) 即某数>sqrt(n)必然木有完美数对 */ const int N=2e5+5; int a[N],cnt[N]; int un[N]; int n,ans; signed main() { std::ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; cnt[a[i]]++; } int sum=0; for(int i=1;i<=sqrt(n);i++)//去重 ---且不过sqrt(n) { if(cnt[i]>=1) un[++sum]=i; } //暴力直接处理:找目表 sort想不出来就不想了 for(int i=1;i<=sum;i++)//二重枚举所以情况 这里其实已经优化了 因为sum已经小n很大 for(int j=1;j<=sum;j++) { if(cnt[un[i]]>=un[j]&&cnt[un[j]]>=un[i]) ans++; } cout<<ans<<"\n"; return 0; }
- 1
信息
- ID
- 598
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 167
- 已通过
- 43
- 上传者