这题真的…想通了是个智障题,没想通思路巨尼玛复杂

串 的 本 质 之 和 开 头 结 尾 的 字 符 相 关 , 也 就 是 只 有 00 , 11 , 01 , 10 四 种 串的本质之和开头结尾的字符相关,也就是只有00,11,01,10四种 串的本质之和开头结尾的字符相关,也就是只有00,11,01,10四种

关键来了,00和11是很特殊的,他们对当前局面不会有任何影响

只 要 存 在 01 或 10 串 , 那 么 00 和 11 就 一 定 可 以 放 下 去 且 不 会 影 响 局 面 只要存在01或10串,那么00和11就一定可以放下去且不会影响局面 只要存在01或10串,那么00和11就一定可以放下去且不会影响局面

若 不 存 在 01 和 10 , 且 同 时 存 在 00 和 11 , 显 然 无 法 放 置 若不存在01和10,且同时存在00和11,显然无法放置 若不存在01和10,且同时存在00和11,显然无法放置

那 么 接 下 来 不 就 无 视 00 和 11 , 只 考 虑 01 和 10 吗 ? \color{Red}那么接下来不就无视00和11,只考虑01和10吗? 那么接下来不就无视00和11,只考虑01和10吗?

当 01 串 和 10 串 相 差 不 超 过 1 时 满 足 条 件 当01串和10串相差不超过1时满足条件 当01串和10串相差不超过1时满足条件

所 以 遍 历 一 遍 数 组 , 每 次 翻 转 能 翻 转 且 次 数 较 多 的 那 个 串 所以遍历一遍数组,每次翻转能翻转且次数较多的那个串 所以遍历一遍数组,每次翻转能翻转且次数较多的那个串

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int t,n,l[maxn];
string s[maxn];
map<string,int>mp;
vector<int>vec;
int main()
{
cin >> t;
while( t-- )
{
mp.clear(); vec.clear();
cin >> n;
int zero=0,one=0,two=0,three=0;
for(int i=1;i<=n;i++)
{
cin >> s[i];
l[i]=s[i].length()-1;
if( s[i][0]=='0'&&s[i][l[i]]=='0' ) zero++;
else if( s[i][0]=='0'&&s[i][l[i]]=='1' ) one++;
else if( s[i][0]=='1'&&s[i][l[i]]=='0' ) two++;
else three++;
string w=s[i];
reverse(w.begin(),w.end() );
mp[w]=1;//翻转后存在vector
}
for(int i=1;i<=n;i++)
{
if( s[i][0]=='0'&&s[i][ l[i] ]=='1'&&!mp[ s[i] ] )
{
if( one-two>1 ) vec.push_back(i),one--,two++;
}
if( s[i][0]=='1'&&s[i][ l[i] ]=='0'&&!mp[ s[i] ])
{
if( two-one>1 ) vec.push_back(i),two--,one++;
}
}
if( !one&&!two&&zero&&three )
cout << -1 << endl;
else
{
int len=vec.size();
cout << len << endl;
for(int i=0;i<len;i++) cout << vec[i] << " ";
cout << endl;
}
}
}