hanyujianke 2020-01-12
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
首先输入一个整数n,代表有n个小朋友。下一行输入n个数,分别代表每个小朋友手里糖的数量。
之后再输入一个整数m,代表下面有m个数。下一行输入这m个数。
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
5 1 2 3 4 5 3 2 3 4
2 4
#include <bits/stdc++.h> using namespace std; int s1[1000100], s2[1000100]; int n1, n2, r; int nexter[1000100]; void getnext(){ //计算出nexter数组 int k = -1, j = 0; nexter[0] = -1; while(j<n2-1){ if(k == -1||s2[k] == s2[j]){ k++, j++; if(s2[j]!=s2[k]) //避免s2[j] = s2[next[j]]的情况,节省时间 nexter[j] = k; else nexter[j] = nexter[k]; } else{ k = nexter[k]; } } } int fun(){ int i = 0, j = 0, flag = 0; while(i<n1){ if(s2[j] == s1[i]||j == -1){ j++, i++; } else{ j = nexter[j]; } if(j == n2){ r = i; //r为子串末尾对应的位数 flag++; //统计条件中次数是否唯一 if(flag == 1) r = i; j = 0; //s2返回到首字符,s1返回到已计数子串首字符的下一位开始查找 i = i-n2+1; if(flag == 2) break; } } return flag; } int main() { int i; scanf("%d", &n1); for(i = 0; i<n1; i++){ scanf("%d", &s1[i]); } scanf("%d", &n2); for(i = 0; i<n2; i++){ scanf("%d", &s2[i]); } getnext(); int t = fun(); if(t == 1) printf("%d %d\n", r-n2+1, r); else printf("-1\n"); return 0; }