题目:http://codeforces.com/contest/950/problem/C
题意:把一个字符串s,切割成0 010 01010 这样的子串,也就是0开头,0结尾的01交替串。
这题我改进了几次自己的算法才过的。不过开始没打算写博客。但是后来看到一个大佬的算法。决定批判一下自己的思考方法。
首先说说自己做这题的思路。
很明显的贪心嘛。0101010这样取。然后再取第二串。然后第一串肯定是最长的。然后根据这个写。优化就可以比如说第二个查到i了。可以更具上一串01的编码位置来让他少搜索后面的。并且因为第一串的长度一定大于等于后面的。所以也可以优化。然后放代码吧。不难理解。
#include<bits/stdc++.h>
#define INF 1e18
#define inf 1e9
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define IOS ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std ;
typedef long long ll;
typedef unsigned long long ull;
const int _max = 200000+50;
const ll mod = 1000000007;
vector<int> v[_max];
string s;
bool t[_max];
int main(){
IOS;
cin>>s;
memset(t,true,sizeof(t));
int cnt = 0,len = s.length();
int i = 0;
while(len){
bool pre = 1;
if(cnt >= 1) i = v[cnt-1][0];
while(!t[i]) i++;
if(s[i] != '0'){
cnt = -1;
break;
}
while(i < s.length()){
len--;
pre = !pre;
v[cnt].push_back(i+1);
t[i] = false;
if(cnt >= 1 && v[cnt].size() < v[cnt-1].size())
i = max(i+1,v[cnt-1][v[cnt].size()]);
if(cnt >= 1 && v[cnt].size() == v[cnt-1].size()) break;
while(!t[i] || pre==s[i]-'0') i++;
}
if(!(v[cnt].size()&1)){
cnt = -1;
break;
}
cnt++;
}
cout<<cnt<<endl;
if(cnt == -1) return 0;
for(int x = 0 ; x < cnt ; x++){
cout<<v[x].size()<<' ';
for(int y = 0 ; y < v[x].size()-1 ; y++)
cout<<v[x][y]<<' ';
cout<<v[x][v[x].size()-1]<<endl;
}
return 0;
}
好了。接下来是大佬的算法。没有改直接贴过来。
/*char s[201000];
vector<int> a[201111];
int main()
{
scanf("%s",s);
int n=strlen(s);
int k=0,len=0;
for(int i=0;i<n;i++)
{
if(s[i]=='0')
{
k++;
a[k].push_back(i+1);
len=max(len,k);
}
else
{
if(k==0)
{
printf("-1\n");
return 0;
}
a[k].push_back(i+1);
k--;
}
}
if(len!=k)
printf("-1\n");
else
{
printf("%d\n",k);
for(int i=1;i<=k;i++)
{
int temp=a[i].size();
printf("%d",temp);
for(int j=0;j<temp;j++)
printf(" %d",a[i][j]);
printf("\n");
}
}
return 0;
}*/
仔细看了的就肯定发现了。大佬的代码和我的代码就是两个思考方式。我是找第一串最长的。这也是大多数人的思考方式。但是,这样就会浪费搜索一些重复字符的时间。要让节约时间,就要把这些搜索也充分利用起来。因为00是只能分开两个存的。所以完全可以同时开vector来存啊。这样换了思路方式之后其实我们只要把这个串遍历一遍就可以出答案了。其实想到了这样贪心就很简单了。但是平时的思维还是太凝固了。以后要注意。有时候要多想想别的办法!