题目大意:将一个2n长度数组,删去两个元素后,两两相加,并放入一个n-1长度的数组b,然后数组b 所有的元素公约数要大于1,也就是说b数组中每个元素要有最大公约数,输出a数组每次存入b数组中两个元素的坐标。
我的思路:根据奇偶相加的原理,奇数+奇数 = 偶数,偶数+偶数 = 偶数,奇数+偶数 = 奇数。
如果b数组全部是偶数则肯定有公约数2,而达到这个目的,a数组每次选择的两个数都必须为奇数或者偶数。
a数组元素个数为偶数个所以只有两种情况:
1.偶数个偶数并且偶数个奇数,可以任意删除两个偶数,或两个奇数。
2.奇数个偶数并且奇数个奇数,此时要删除一个奇数加一个偶数达到偶数个偶数,偶数个奇数的状态。
根据以上两种情况便可以完成这道题。
2n 个数去掉两个为 2n-2 再除以2也就是b数组的元素个数 n-1,所以不用考虑b数组的元素个数。
//1370B
#include <iostream>
#include <vector>
using namespace std;
const int Max = 2005;
int n;
void solve()
{
vector<int> a_even; //存放a数组偶数坐标
vector<int> a_odd;//存放a数组奇数坐标
cin >> n;
int c;
for (int i = 1; i <= 2 * n; i++)
{
cin >> c;
if (c & 1) a_odd.push_back(i);
else a_even.push_back(i);
}
if ((a_odd.size() & 1) &&( a_even.size() & 1))
{
a_odd.pop_back();
a_even.pop_back();
}
else if (!a_odd.empty())
{
a_odd.pop_back();
a_odd.pop_back();
}
else
{
a_even.pop_back();
a_even.pop_back();
}
if (!a_odd.empty())
{
for (int i = 0; i < a_odd.size() - 1; i += 2)
{
cout << a_odd[i] << " " << a_odd[i + 1] << endl;
}
}
if (!a_even.empty())
{
for (int i = 0; i < a_even.size() - 1; i += 2)
{
cout << a_even[i] << " " << a_even[i + 1] << endl;
}
}
return;
}
int main()
{
int t;
cin >> t;
while (t--)
{
solve();
}
}