字符串的最小表示--nkoj2973质检员

质检员

Description

何老板的工厂生产一种宝石项链,该项链由n颗宝石构成。构成项链的宝石有10种,编号0到9。生产出的项链有些是不合格的,作为质检员,你的工作是把不合格的产品找出来。何老板给你一个合格项链的样品和m(编号1到m)条刚生产出的项链,你要把不合格的项链找出来,并输出它的编号。

Input

第一行,两个整数n和m。 
第二行,n个空格间隔的整数,表示样品项链,每个整数表示一颗宝石 
接下来m行,每行n个空格间隔的整数,表示一条产品项链。

Output

一行,若干个由小到大的空格间隔的整数,表示不合格产品的编号 

Sample Input

4 4
5 1 2 8
2 8 5 1
1 8 5 2
8 5 1 2
1 5 8 2

Sample Output

2 4

Hint

样例说明: 
将给出的数字连成一圈,转动一下,你会发现第1和第3条项链与给出的样品是一样的 
数据范围: 
30% 1<=n,m<=10 
60% 1<=n,m<=100 
100% 1<=n,m<=1000

#include<cstdio>
#include<iostream>
using namespace std;
int temp[5005],ans[5005],a[5005],g[5005];
int main(){
	int n,m,i,j,k,cnt=0,h,c,q=0;
	cin>>n>>m;
	for(i=0;i<n;i++){
		scanf("%d",&temp[i]);
		temp[i+n]=temp[i];
	}
	i=0;j=1;
	while(i<n&&j<n){
		for(k=0;k<n;k++)
			if(temp[i+k]!=temp[j+k])break;
		if(k==n)break;
		if(temp[i+k]>temp[j+k])i=i+k+1;
		else if(temp[i+k]<temp[j+k])j=j+k+1;
		if(i==j)j++;
	}
	for(k=min(i,j);k<=min(i,j)+n-1;k++){
		ans[cnt++]=temp[k];
	}
	for(h=1;h<=m;h++){
		for(j=0;j<n;j++){
			scanf("%d",&temp[j]);temp[j+n]=temp[j];
		}
		i=0;j=1;cnt=0;
		while(i<n&&j<n){
			for(k=0;k<n;k++)
				if(temp[i+k]!=temp[j+k])break;
			if(k==n)break;
			if(temp[i+k]>temp[j+k])i=i+k+1;
				else if(temp[i+k]<temp[j+k])j=j+k+1;
			if(i==j)j++;
		}
		for(k=min(i,j);k<=min(i,j)+n-1;k++){
			a[cnt++]=temp[k];
		}
		for(c=0;c<n;c++){
			if(ans[c]!=a[c])break;
		}
		if(c!=n)g[++q]=h;
	}
	for(i=1;i<=q;i++)printf("%d ",g[i]);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值