https://vjudge.net/problem/Gym-102536B
題意:
給出一個n長01串,找出不超過n個01串,滿足1的個數恰好爲m,所有01串異或起來全部爲1。
解析:
可以考慮將所有串分爲兩種:
- 單個串使用,可以改變位數m。
- 兩個串一起用,可以改變位數爲2m,2m-2,2m-4…。
由於不要求最少,所以可以兩個串改兩個位置例如1111 10,1111 01。
如果開始時剩餘0的數量爲奇數,此時如果m偶數則不行,否則改變m位,使剩下的0的數量爲偶數。之後兩個兩個消除0。
正確性:
第一次奇數變偶數一定可以剩下一個1,之後2換2,所以一定可以在n個之內消除完0。
注意特判一些情況。
代碼:
/*
* Author : Jk_Chen
* Date : 2020-03-15-13.19.24
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=100;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
char x[maxn];
char ans[maxn][maxn];
int main(){
int t=rd;
while(t--){
int n=rd,m=rd;
rep(i,1,n){
rep(j,1,n)ans[i][j]='0';
ans[i][n+1]='\0';
}
scanf("%s",x+1);
vector<int>Z,O;
rep(i,1,n){
if(x[i]-'0')O.pb(i);
else Z.pb(i);
}
if(Z.empty()){
puts("0");
continue;
}
if(Z.size()%2&&!(m%2)){
puts("CATACLYSM IMMINENT - TIME TO HOARD FACE MASKS");
continue;
}
if(Z.size()&&m==n){
if(Z.size()==n){
printf("1\n");
rep(i,1,n)putchar('1');
puts("");
continue;
}
puts("CATACLYSM IMMINENT - TIME TO HOARD FACE MASKS");
continue;
}
int now=0;
if(Z.size()%2){
if(Z.size()>=m){
now++;
rep(i,1,m){
ans[now][Z.back()]='1';
O.pb(Z.back());
Z.pop_back();
}
}
else{
now++;
vector<int>tZ,tO;
int nZ=Z.size();
int nO=m-nZ;
rep(i,1,nZ){
tZ.pb(Z.back());
ans[now][Z.back()]='1';
Z.pop_back();
}
rep(i,1,nO){
tO.pb(O.back());
ans[now][O.back()]='1';
O.pop_back();
}
while(tZ.size()){
O.pb(tZ.back());tZ.pop_back();
}
while(tO.size()){
Z.pb(tO.back());tO.pop_back();
}
}
}
while(Z.size()){
now+=2;
int a1=Z.back();Z.pop_back();
int a2=Z.back();Z.pop_back();
int ct=m-1,ar=1;
while(ct){
if(ar!=a1&&ar!=a2){
ans[now-1][ar]='1';
ans[now][ar]='1';
ct--;
}
ar++;
}
ans[now-1][a1]='1';
ans[now][a2]='1';
}
assert(now<=n);
rep(i,1,n){
int sta=x[i]-'0';
rep(j,1,now){
sta^=ans[j][i]-'0';
}
if(!sta)while(1);
}
printf("%d\n",now);
rep(i,1,now){
puts(ans[i]+1);
}
}
return 0;
}
/*
100
4 4
0000
4 2
1100
5 3
11110
7 7
1111111
7 7
1111110
7 1
1111110
10 9
1001101101
*/
/*_________________________________________________________end*/