题目分析:按照题意感觉是一道模拟题,但是还是需要枚举满足题意的方法(虽说只需要求出一种),用DFS做,感觉更好。
下面是代码:
#include <iostream>
#include <string>
using namespace std;
#define maxn 1010
string s;
int m;
int A[maxn];
bool ok;
//其中left和right分别为当前天平两边托盘的重量
//cnt表示是第几次放,一共放m次
//cur表示上次放的重量,因为题目说连续两次放的砝码重量不能相同
void dfs_right(int left,int right,int cnt,int cur);
void dfs_left(int left,int right,int cnt,int cur);
//放右边天平托盘
void dfs_right(int left,int right,int cnt,int cur)
{
if(cnt == m)
{
ok = true;
return ;
}
for(int i = 0; i < s.size(); i++)
{
if(ok) return ;
if(s[i] == '1')
{
int val = i+1;
if(right + val > left && val != cur)
{
//cout<<"right"<<cnt+1<<" "<<val<<endl;
A[cnt] = val,dfs_left(left,right+val,cnt+1,val);
}
}
}
}
//放左边天平托盘
void dfs_left(int left,int right,int cnt,int cur)
{
if(cnt == m )
{
ok = true;
return ;
}
for(int i = 0; i < s.size(); i++)
{
if(ok) return ;
if(s[i] == '1')
{
int val = i+1;
if(left + val > right && val != cur)
{
//cout<<"left"<<cnt+1<<" "<<val<<endl;
A[cnt] = val,dfs_right(left+val,right,cnt+1,val);
}
}
}
}
int main()
{
cin>>s>>m;
ok = false;
dfs_left(0,0,0,0);
if(ok)
{
cout<<"YES\n";
cout<<A[0];
for(int i = 1; i < m; i++) cout<<" "<<A[i];
cout<<endl;
}
else cout<<"NO\n";
return 0;
}
PS:可以把两个dfs合并为一个,囧