B.渐进式广场B.渐进式广场B.渐进式广场 每次测试时限:2秒每次测试时限:2 秒每次测试时限:2秒 每次测试的内存限制:256兆字节每次测试的内存限制:256 兆字节每次测试的内存限制:256兆字节
题目描述
大小为 nnn 的累进正方形是一个 n×nn \times nn×n 矩阵。马克西姆选择三个整数 a1,1a_{1,1}a1,1 、 ccc 和 ddd ,并根据以下规则构造一个累进正方形:
ai+1,j=ai,j+c a_{i+1,j} = a_{i,j} + c ai+1,j=ai,j+c
ai,j+1=ai,j+d a_{i,j+1} = a_{i,j} + d ai,j+1=ai,j+d
例如,如果 n=3n = 3n=3 、 a1,1=1a_{1,1} = 1a1,1=1 、 c=2c=2c=2 和 d=3d=3d=3 ,那么递进方格如下:
(1473695811) \begin{pmatrix} 1 & 4 & 7 \\ 3 & 6 & 9 \\ 5 & 8 & 11 \end{pmatrix} 1354687911
上个月,马克西姆构建了一个递阶方阵,并记住了 nnn 、 ccc 和 ddd 的值。最近,他发现了一个由 n2n^2n2 个整数随机排列而成的数组 bbb ,并想确定这些元素就是那个特定正方形的元素。
可以证明,对于 nnn 、 a1,1a_{1,1}a1,1 、 ccc 和 ddd 中的任意值,恰好存在一个满足所有规则的递进正方形。
输入
第一行包含一个整数 ttt ( 1≤t≤1041 \le t \le {10} ^ 41≤t≤104 ) - 测试用例的数量。
每个测试用例的第一行包含三个整数 nnn 、 ccc 和 ddd ( 2≤n≤5002 \le n \le 5002≤n≤500 , 1≤c,d≤1061 \le c, d \le 10^61≤c,d≤106 )–正方形的大小以及语句中描述的 ccc 和 ddd 的值。
每个测试用例的第二行包含 n⋅nn \cdot nn⋅n 个整数 b1,b2,…,bn⋅nb_1, b_2, \dots, b_{n \cdot n}b1,b2,…,bn⋅n ( 1≤bi≤1091 \le b_i \le 10^91≤bi≤109 ) - 马克西姆找到的元素。
保证所有测试用例中 n2n ^ 2n2 的总和不超过 25⋅10425 \cdot {10} ^ 425⋅104 。
输出
对于每个测试用例,如果可以用数组元素 aaa 构建出给定的 nnn 、 ccc 和 ddd 的渐进正方形,则另起一行输出 “是”,否则输出 “否”。
您可以以任何大小写(小写或大写)输出每个字母。例如,字符串 “yEs”、“yes”、"Yes "和 "YES "将被视为肯定答案。
思路:
我们可以发现当最小值确定时,它所对应的累进正方形里面的各个值也就跟着确定下来了。所以可以先找到给定数组中的最小值,然后利用该最小值去推出正确的累进正方形中的值因该是什么,然后与给定的数组中的元素去比较就可以了。
细节:
这道题目要注意一个很重要的细节——>不要使用unordered_map,要使用map
。
为什么呢?这是因为unordered_map是通过哈希表实现的,虽然平均时间复杂度为O(1)O(1)O(1),但是不太稳定,当数据比较刁钻或者设计的哈希函数不合理的时候,会使得各个键值对的键带入哈希函数得到的哈希值始终相同,从而使得所有键值对始终存储在同一链表上,这样会导致时间复杂度降为O(n)O(n)O(n)。
而map
是通过红黑树
实现的,虽然平均时间复杂度为O(logn)O(logn)O(logn),但是非常的稳定。
下图中第二个是使用了
map
,第一个是使用了unordered_map
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
bool solve()
{
int Min=2e9;
map<int,int>mp; //注意这里必须要用map,不要使用unordered_map
int n,c,d; cin>>n>>c>>d;
for(int i=1;i<=n*n;i++)
{
int temp; cin>>temp;
mp[temp]++;
Min=min(Min,temp);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(mp[Min+(j-1)*d]==0)return false;
else mp[Min+(j-1)*d]--;
Min+=c;
}
return true;
}
int main()
{
int t; cin>>t;
while(t--)
{
if(solve())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}