ZOJ 3675 Trim the Nails(DFS)

来源:互联网 发布:ubuntu 微信调试工具 编辑:程序博客网 时间:2024/05/21 07:59
Trim the Nails

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Robert is clipping his fingernails. But the nail clipper is old and the edge of the nail clipper is potholed.

The nail clipper's edge is N millimeters wide. And we use N characters('.' or '*') to represent the potholed nail clipper. '.' represents 1 bad millimeter edge, and '*' represents 1 good millimeter edge.(eg. "*****" is a 5 millimeters nail clipper with the whole edge good. "***..." is a 6 millimeters nail clipper with half of its edge good and half of its edge bad.)

Notice Robert can turn over the clipper. Turning over a "**...*"-nail clipper will make a "*...**"-nail clipper.

One-millimeter good edge will cut down Robert's one-millimeter fingernail. But bad one will not. It will keep the one-millimeter unclipped.

Robert's fingernail is M millimeters wide. How many times at least should Robert cut his fingernail?

Input

There will be multiple test cases(about 15). Please process to the end of input.

First line contains one integer N.(1≤N≤10)

Second line contains N characters only consists of '.' and '*'.

Third line contains one integer M.(1≤M≤20)

Output

One line for each case containing only one integer which is the least number of cuts. If Robert cannot clipper his fingernail then output -1.

Sample Input

8****..**46*..***7

Sample Output

12

Hint

We use '-' to present the fingernail.For sample 1:fingernail:----nail clipper:****..**Requires one cut.For sample 2:fingernail:-------nail clipper:*..***nail clipper turned over: ***..*Requires two cuts.
题意 :先输入一个n代表指甲刀的长度,再输入一个字符串如果是‘*’代表是完好的,‘.’。之后输入一个m代表指甲的长度。注意这里的指甲到可以反转,输出最少要剪几次才能把指甲都剪了。
思路:这里只要一个特判就是当指甲刀都是坏的话就输出‘-1’。用一个l代表指甲刀左端第一个完好的位置,l代表右端第一个完好的位置。每次都是从指甲的左端开始剪,s代表最左端没有剪的指甲位置,其中的flag是1的话代表指甲刀从左端开始剪,0的话从右端。dfs中i代表指甲位置,j代表指甲刀位置,当i==m+1时代表全部指甲都剪了,就比对step和MIN的大小。
#include<stdio.h>#include<string.h>int n,m,l,r,MIN;int a[111];void dfs(int b[],int s,int flag,int step){int i,j;int c[28];//代表此时指甲的状态,如果为1代表剪了,0就是没剪if(step>=MIN)return;for(i=1;i<=23;i++)c[i]=b[i];if(flag)//从左端开始剪{for(i=s,j=l;i<=m&&j<=n;i++,j++)//i代表指甲位置,j代表指甲刀位置{if(c[i]==0)c[i]=a[j];//指甲和指甲刀的匹配,如果指甲没剪而在这个位置指甲刀又是完好的就剪}for(i=s;i<=m;i++){if(c[i]==0)//判断是不是都剪了{s=i;break;}}if(i==m+1){if(step<MIN)MIN=step;return;}dfs(c,s,1,step+1);//匹配下一个从s位置开始的指甲dfs(c,s,0,step+1);}else{for(i=s,j=r;i<=m&&j>=1;i++,j--)//从右端开始剪,注意这个j>=1{if(c[i]==0)c[i]=a[j];}for(i=s;i<=m;i++){if(c[i]==0){s=i;break;}}if(i==m+1){if(step<MIN)MIN=step;return;}dfs(c,s,1,step+1);dfs(c,s,0,step+1);}}int main(){int i;char str[111];int b[111];while(scanf("%d",&n)!=EOF){scanf("%s",str+1);for(i=1;str[i]!='\0';i++){if(str[i]=='*')a[i]=1;elsea[i]=0;}scanf("%d",&m);l=0;r=n;for(i=1;i<=n;i++){if(a[i]==1){l=i;break;}}for(i=n;i>=1;i--){if(a[i]==1){r=i;break;}}if(l==0){printf("-1\n");continue;}MIN=99999999;memset(b,0,sizeof(b));dfs(b,1,1,1);dfs(b,1,0,1);printf("%d\n",MIN);}return 0;}


原创粉丝点击