#include<bits/stdc++.h>
using namespace std;
template <typename T>
void read(T &x) {
int f = 1;
x = 0;
char c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
char s[100005];
struct node{
int id,len,num;
}f[100005];
int l[100005],r[100005];
bool cmp(node x,node y){
if(x.num*y.len!=y.num*x.len)
return x.num*y.len>y.num*x.len;
else
return x.num<y.num;
}
int use[100005];
int main(){
freopen("tiaoxingma.in","r",stdin);
freopen("tiaoxingma.out","w",stdout);
int T;
read(T);
for(;T;T--){
memset(use,0,sizeof(use));
int n,k;
read(n),read(k);
scanf("%s",s+1);
int tot=1;
f[tot].id=1;
f[tot].len=1;
f[tot].num=1;
for(int i=2;i<=n;i++){
if(s[i]!=s[i-1]){
f[++tot].id=i;
f[tot].len=1;
f[tot].num=2;
} else {
f[tot].len++;
}
}
f[tot].num--;
int l_len=f[1].len;
int r_len=f[tot].len;
sort(f+1,f+1+tot,cmp);
int l_id=0;
int r_id=0;
for(int i=1;i<=tot;i++){
if(f[i].id==1) l_id=i;
if(f[i].id+f[i].len-1==n) l_id=i;
}
int cnt=tot;
int st=1;
// int ans=0;
while(cnt>k){
if(cnt-k==1){
bool can_l=false,can_r=false;
if(l_len*2>f[st].len&&!use[l_id]) can_l=true;
if(r_len*2>f[st].len&&!use[r_id]) can_r=true;
if(can_l==true&&can_r==true){
if(f[l_id].len<f[r_id].len) can_r=false;
if(f[l_id].len>f[r_id].len) can_l=false;
}
if(can_l==true&&can_r==false){
for(int j=f[l_id].id;j<=f[l_id].id+f[l_id].len-1;j++) s[j]='0'+'1'-s[j];
cnt--;
continue;
}
if(can_l==false&&can_r==true){
for(int j=f[r_id].id;j<=f[r_id].id+f[r_id].len-1;j++) s[j]='0'+'1'-s[j];
cnt--;
continue;
}
}
use[st]=true;
cnt-=f[st].num;
for(int j=f[st].id;j<=f[st].id+f[st].len-1;j++) s[j]='0'+'1'-s[j];
use[st+1]=true;
use[st-1]=true;
for(;st<=tot;st++){
if(use[st]==false) break;
}
}
for(int i=1;i<=n;i++) printf("%c",s[i]);
printf("\n");
}
return 0;
}
/*
3
9 3
000111000
10 3
0111011010
4 4
0001
*/
题目略不一样,就是改为放K个皇后。
用位运算优化
@Shendu.CC
没啥高明的解法,就百度里说的回溯法。如果用栈,可能会简单一点
好的。那么广搜呢?
@Shendu.CC: 没听过呀,孤陋寡闻了。
@会长: 为什么用栈会简单呢?用栈模拟递归吗?
@Shendu.CC: n个位置都不满足条件就可以把上一个皇后出栈重新安排位置,感觉容易点
@Shendu.CC:
class Queen(object):
def __init__(self, row, column):
self.__row = row
self.__column = column
@property
def row(self):
return self.__row
@row.setter
def row(self, value):
self.__row = value
@property
def column(self):
return self.__column
@column.setter
def column(self, value):
self.__column = value
def valid(row, column, stack):
for item in stack:
if item.row == row:
return False
if item.column == column:
return False
if abs(item.row - row) == abs(item.column - column):
return False
return True
def fuckQueen(n):
row = 0
column = 0
stack = []
while row < n:
done = False
for column_index in range(column, n):
if valid(row, column_index, stack):
stack.append(Queen(row, column_index))
done = True
row += 1
column = 0
break
if done == False:
queen = stack.pop()
row -= 1
column = queen.column + 1
return stack
if __name__ == "__main__":
stack = fuckQueen(4)
for item in stack:
print(item.row, ' ', item.column)
我只给出一个解,没有遍历所有解,不管怎么说,用了栈,你不用栈试试会不会比这个复杂
@会长: 稍等哦。
@Shendu.CC: 刚才有个地方写错了,我改了下,应该是break,不是continue
@会长:
c++ 递归
class Solution {
public:
vector<vector<string>> ans;
int a[100][100];
int m;
vector<vector<string>> solveNQueens(int n) {
m=n;
memset(a,0,sizeof(a));
fun(0);
return ans;
}
void fun(int pos)
{
if(pos==m)
{
ans.push_back(getString());
return;
}
for(int i=0;i<m;i++)
{
if(a[pos][i]==0)
{
a[pos][i]=1;
setLock(pos,i,2);
fun(pos+1);
setLock(pos,i,-2);
a[pos][i]=0;
}
}
}
void setLock(int x,int y,int num)
{
for(int i=x+1;i<m;i++)
{
a[i][y]+=num;
}
int tag=1;
for(int i=x+1;i<m;i++)
{
if(y+tag<m)
a[i][y+tag]+=num;
if(y-tag>=0)
a[i][y-tag]+=num;
tag++;
}
}
vector<string> getString()
{
vector<string> res;
for(int i=0;i<m;i++)
{
string s="";
for(int j=0;j<m;j++)
{
if(a[i][j]==1)
{
s+='Q';
}
else
s+='.';
}
res.push_back(s);
}
return res;
}
};
@会长: https://leetcode.com/problems/n-queens/
你可以用python把这道题目过一下,我不会python 不好改你的代码。
@Shendu.CC: 我没看懂,啊哈哈。我小时候上学老师出过这个题目,记得当时不会写,从网上找的代码,不过没有用到栈,也是回溯法。感觉用栈方便一些。
关键代码的行数,我看你的c++代码比我的python代码还多一点。虽然看不懂,但是我觉得用栈代码会少一点,你用栈试试
@会长: @会长: 我用了 栈的
https://leetcode.com/problems/n-queens-ii/
过了这一题。
class Solution {
public:
int ans=0;
int a[100][100];
int m;
int x[100005];
int y[100005];
int s[100005];
int p[100005];
int totalNQueens(int n) {
m=n;
memset(a,0,sizeof(a));
int pos=0;
s[pos]=0;
x[pos]=-1;
y[pos]=-1;
p[pos]=-1;
pos++;
while(pos!=0)
{
int i=s[pos-1];
if(i==n)
{
ans++;
}
if(p[pos-1]<=n-1&&i!=n)
{
p[pos-1]++;
while(a[i][p[pos-1]]!=0)
{
p[pos-1]++;
}
if(p[pos-1]!=n){
a[i][p[pos-1]]=1;
setLock(i,p[pos-1],2);
s[pos]=i+1;
x[pos]=i;
y[pos]=p[pos-1];
p[pos]=-1;
pos++;
continue;
}
}
if(pos==1)
break;
a[x[pos-1]][y[pos-1]]=0;
setLock(x[pos-1],y[pos-1],-2);
pos--;
}
return ans;
}
void setLock(int x,int y,int num)
{
for(int i=x+1;i<m;i++)
{
a[i][y]+=num;
}
int tag=1;
for(int i=x+1;i<m;i++)
{
if(y+tag<m)
a[i][y+tag]+=num;
if(y-tag>=0)
a[i][y-tag]+=num;
tag++;
}
}
};
@Shendu.CC: 赞
可以用位运算优化