1 条题解
-
0
思路
题意:有 个信号强度 和周期长度 ,信号按规则分入 个频段,规则保证“强度相差 的整数倍的两个信号落进同一频段”。求信号数最多的频段里有多少个信号。
把“频段”翻译成取模
题面只说明了充分条件: 同一频段。而频段总数为 ,且编号由强度在长度为 的周期内的位置决定,因此频段编号就是 这一余数类:
- 余数相同 ⇒ 差是 的倍数 ⇒ 必在同一频段;
- 余数不同 ⇒ 差不是 的倍数 ⇒ 不可能同频段( 个余数恰好对应 个频段)。
所以问题转化为:统计所有 的出现次数,输出最大值。
实现
- 读入 ,用
map<int,int>记录每个余数出现的次数:cnt[x % m]++; - 由于 ,取模不会出现负数,无需额外修正;
- 遍历
map中所有键值对,取最大的计数作为答案。
用
map而不是长度为 的数组,是因为 可能远大于 ,数组会浪费空间;map的实际条目数不超过 。cnt定义在go()内部,因此每组测试自动清空。复杂度
每组数据时间 (
map插入与遍历),空间 。题目保证 ,完全够用。代码
#include<bits/stdc++.h> #define int long long #define dd double #define str string #define el cout << '\n' #define re return #define ff first #define ss second #define pll pair<int,int> #define pdd pair<dd,dd> #define all(x) x.begin(),x.end() #define pb push_back using namespace std; // 每组测试:统计各余数(频段)的信号数,输出最大值 void go(){ int n, m;cin>>n>>m; map<int, int>cnt; // 键为余数(即频段编号),值为该频段的信号数 for(int i=1;i<=n;i++){ int x;cin>>x; cnt[x%m]++; // a_i >= 1,取模结果非负,直接作为频段编号 } // 取所有频段中信号数的最大值 int ans = 0; // 信号数最多的频段所包含的信号数 for(auto [num, c]:cnt){ ans = max(ans, c); } cout<<ans;el; // 输出最大信号数 } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int _=1; cin >>_; // 读入测试组数 T while(_--){ go(); } return 0; }
- 1
信息
- ID
- 41
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者