一个序列长度为n的序列P(1,n),构造一个序列Q,长度为N并且由1~N组成。一开始Qn对在P1的位置,接下来每秒Q都会整体右移一个位置,直到2N秒后和P没有交集。Ai代表第i秒P和Q交集元素的个数,Bi代表位置重合并且元素相等的元素个数。令Ci=max(Ai-Bi),构造一个序列,使Ci最小。
Ci最小是N-sqrt(N),官方题解说的比较详细。构造序列这个地方看了半天才看明白他是怎么构造的,对于S序列,可以这么理解:给出一个序列x[1,n],以及S(a1,a2,a3....),对应的操作就是先把x[1~a1]翻转,再把[a1+1,a1+a2+1]翻转....,比如x[]=(1,2,3,4,5,6,7),S[]=(1,2,3),那么操作完的序列就是x[]=(1, 3,2, 6,5,4, 7)。。而这题对应的S序列就是S[]=(1,2,3...D-1,1,2,3....D),D=N-sqrt(N)。其实这么构造也不难理解,两个顺序相反数字相同的序列,在相遇的第1,3,5。。7秒都会有且仅有1个位置相同并且数字相同的树。。想到这点差不多就明白这题为什么这样构造了。。
1 #include2 #include 3 int cas, n; 4 int main(){ 5 scanf("%d", &cas); 6 for (int ca = 1; ca <= cas; ca++) { 7 scanf("%d", &n); 8 int d = (int)sqrt(n + 0.5), p = 1; 9 printf("Case #%d: %d\n",ca, n - d);10 for (int i = 0; i < 2; i++)11 for (int j = 1; j < d + i; j++)12 for (int x = 1, k = p; x <= j; x++)printf("%d%c", k + j - x, p++==n ? '\n':' ');13 for (; p <= n; p++) printf("%d%c", p, p==n ? '\n':' ');14 }15 return 0;16 }