1 条题解
-
0
字符串处理就不说了,暴力的 时间应该也没有问题,不过最好用 KMP,这题的重点是后面的处理。
如果 或者 ,所有人直接逃跑即可;
如果 ,用时最短的和用时最长的一起过去,然后用时最短的回来,再和剩下的一个过去;
如果 ,设 表示用时最短的人所用的时间, 为用时第二短的人所用的时间, 表示用时最长的人所用的时间, 表示用时第二长的人所用的时间。那么:
当 时,就先让用时最短的人和用时最长的人一起过去,然后用时最短的回来,接着让用时最短的和用时第二长的一起过去,再让用时最短的回来。
否则,就先让用时最短的和用时第二短的一起过去,然后用时最短的回来,接着让用时最长和用时第二长的一起过去,再让用时第二短的回来。这样就相当于剩下了 个人。对这 个人执行相同的操作,知道剩下不足 个人即可。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[1005]; int KMP() { int p[100010]; char a[100010],b[100010]; scanf("%s%s",a,b); int i,j,siza=strlen(a), sizb=strlen(b); j=p[0]=-1; for(i=1; i<sizb; ++i) { while(j>=0 && b[j+1]!=b[i]) j=p[j]; if(b[j+1]==b[i]) ++j; p[i]=j; } j=-1; int ok=0; int sum=0; for(i=0; i<siza;++i) { while(j>=0 && b[j+1]!=a[i]) j=p[j]; if(b[j+1]==a[i]) ++j; if(j==sizb-1) { sum++; j=p[j]; } } return sum; } int main() { int T, n, i; scanf("%d",&n); for(i = 0; i < n; i++) a[i]=KMP(); sort(a,a+n); int sum=0; while(n>=4) { if((a[1] * 2 + a[n-1] + a[0]) > (2 * a[0] + a[n-1] + a[n-2])) { sum += a[n-1]; sum += a[0]; sum += a[n-2]; sum += a[0]; } else { sum += a[1]; sum += a[0]; sum += a[n-1]; sum += a[1]; } n -= 2; } if(n == 3)sum += a[1] + a[0] + a[2]; else if(n == 2)sum += a[1]; else sum += a[0]; printf("%d\n",sum); return 0; }
- 1
信息
- ID
- 12
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者