A题: 思路: 这道题首先观察题目性质可以得到:只有当ai 和 aj存在倍数关系时才能得到 ai | aj >= lcm(ai, aj); 证明: ai | aj <= ai + aj 因为按位或是不进位加法,所以两个数按位或一定小于等于两个数相加 若ai 和 aj 均大于 1 时,ai * aj >= ai + aj >= ai | aj; lcm(ai,aj) >= ai * aj, 当取等于时,ai 和 aj存在倍数关系,所以只有当ai 和 aj存在倍数关系时,才可能取到ai | aj >= lcm(ai, aj); 若ai 和 aj存在一个数位1时,ai 与 aj之间肯定存在倍数关系 至此可以证明只有ai 和 aj 之间存在倍数关系时,可以得到ai | aj >= lcm(ai, aj);
#include"bits/stdc++.h"
using namespace std;
const int N = 2e5 + 10, M = 2E6 + 10;
int a[N];
bool st[M];
map<int,int>f;
int main()
{
int n;
cin >> n;
int maxn = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d", &a[i]), maxn = max(maxn, a[i]);
if(st[a[i]])
{
cout << f[a[i]] + 1 << ' ' << i + 1 << endl;
return 0;
}
f[a[i]] = i;
st[a[i]] = true;
}
sort(a , a + n);
for(int i = 0; i < n ;i ++)
{
if(a[i] * 2 > maxn)break;
int k = 2;
while(a[i] * k <= maxn)
{
if(st[a[i] * k])
{
cout << min(f[a[i]], f[a[i] * k]) + 1 << ' ' << max(f[a[i]], f[a[i] * k]) + 1;
return 0;
}
++ k;
}
}
cout << -1;
}
B题: 思路:直接模拟。(每个人可以根据自己的想法来完成代码) 注意事项: 你所构造的m中排序中,必须满足每个人在这m种排序中的位置的最小值等于题目所给定的最小值 也就是说你构造的序列 a11…a1n a21…a2n … am1…amn 任意的第i列的最小值必须等于x[i] (1 <= i <= n) x[i]为题目所给定的每个人的位置
#include"bits/stdc++.h"
using namespace std;
const int N = 2010;
vector<int>f[N];
vector<int>res[N];
vector<int>ans[N];
set<int>s[N];
int n , m, x[N], mini[N];
void solve(int nn,int k)
{
if(nn == 0)return ;
nn -= f[k].size();
if(f[k].size() > m)
{
cout << "No";
exit(0);
}
for(int i = 0; i < f[k].size(); i ++)
res[i].push_back(f[k][i]), s[i].insert(f[k][i]);
int t = f[k].size();
while(t < m)
{
bool flag = false;
for(int i = 0; i <= k ;i ++)
{
for(int j = 0; j < f[i].size(); j ++)
{
if(!s[t].count(f[i][j]))
{
res[t].push_back(f[i][j]);
s[t].insert(f[i][j]);
flag = true;
break;
}
}
if(flag)break;
}
if(!flag)
{
cout << "No";
exit(0);
}
t ++;
}
solve(nn, k + 1);
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n ;i ++)
{
s[i].clear();
cin >> x[i];
f[x[i]].push_back(i);
}
solve(n, 1);
for(int i = 0 ;i < m ;i ++)
{
if(res[i].size() < n)
{
for(int j = 1; j <= n ;j ++)
if(!s[i].count(j))
res[i].push_back(j);
}
}
memset(mini, 0x3f, sizeof mini);
for(int i = 0 ;i < m ;i ++)
{
for(int j = 0; j < n ;j ++)
{
ans[res[i][j]].push_back(j + 1);
mini[res[i][j]] = min(mini[res[i][j]], j + 1);
}
}
for(int i = 1; i <= n ;i ++)
if(mini[i] != x[i])
{
cout << "No";
return 0;
}
cout << "Yes" << endl;
for(int i = 1; i <= n ;i ++)
{
for(int j = 0 ;j < m ;j ++)
if(j == 0)printf("%d", ans[i][j]);
else printf(" %d", ans[i][j]);
cout << endl;
}
}```
|