2021(CCPC)- 网络选拔赛Time-division Multiplexing(双指针)

Time-division Multiplexing

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1706    Accepted Submission(s): 370


 

Problem Description
Time-division multiplexing (TDM) is a method of transmitting and receiving independent signals over a common signal path by means of synchronized switches at each end of the transmission line so that each signal appears on the line only a fraction of time in an alternating pattern. This method transmits two or more digital signals or analog signals over a common channel.

The time domain is divided into several recurrent time slots of fixed length, one for each sub-channel. A sample byte or data block of sub-channel 1 is transmitted during time slot 1, sub-channel 2 during time slot 2, etc. One TDM frame consists of one time slot per sub-channel plus a synchronization channel and sometimes error correction channel before the synchronization. After the last sub-channel, error correction, and synchronization, the cycle starts all over again with a new frame, starting with the second sample, byte or data block from sub-channel 1, etc.

There are n time slots in total now, each of which periodically transmits a string only containing lowercase letters. You need to find the shortest slot length that contains all the different letters transmitted totally.
 

Input
This problem contains multiple test cases.

The first line contains a single integer T (1≤T≤100) indicating the number of test cases. 

For each test case, the first line contains a single integer n(1≤n≤100). Then next n lines, each line contains a string si only containing lowercase letters. The length of each string is no more than 12.

It is guaranteed that the ∑n≤2000.
 
Output
For each test case, output a single integer in a line, the answer for the test case.
 
Sample Input
2
2
abc
bd
2
bab
bbc
 
Sample Output

4

4

Hint
In the first sample, there are two time slots in total and s1 = abc, s2 = bd. Letters transmitted on the channel are as follows: abbdcbad... We can choose dcba as the answer string so the answer is 4.

思路:

(题意挺难看懂的)

题意就是按给定字符串的顺序 ,s1,s2,s3,s4....sn 每个字符串再按自己的顺序出一个字符到数组b[]中,无限循环,然后从b[i]中找出一个最短子串让其包含所有字符

b[]直接暴力

注意一下b[]中存两遍循环节(因为可能从交界处取)就行了

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int book[10013],pos[10101],len[11000],m,n,inf=0x3f3f3f3f,k;
char a[10001][60],b[11770100];
int check()
{
	for(int i=0; i<n; i++)
	{
		if(pos[i])  return 0;
	}
	return 1;
}
void init()
{
	int i;
	k=-1;
	memset(pos,0,sizeof(pos));
	i=0;
	while(!(check()&&i==0)||k==-1)/*第二次pos[1~n]=0(同时==0)*/
	{
		b[++k]=a[i][pos[i]];
		pos[i]=(pos[i]+1)%len[i];
		i=(i+1)%n;
	}
	int L=k;

	for(i=0; i<=L; i++)/*再扩大一倍*/
		b[++k]=b[i];

	b[++k]='\0';
}
int main()
{
	int j,i,w,head,tail,min1,sum,sum1;
	scanf("%d",&w);
	while(w--)
	{
		scanf("%d",&n);
		sum1=0;
		memset(book,0,sizeof(book));
		for(i=0; i<n; i++)
		{
			scanf("%s",a[i]);
			len[i]=strlen(a[i]);

			for(j=0; j<len[i]; j++)
				if(!book[a[i][j]])
				{
					sum1++;
					book[a[i][j]]=1;
				}
		}

		init();
		/*尺取*/
		tail=head=sum=0;
		memset(book,0,sizeof(book));/*记录字符在尺取段中出现的次数*/
		min1=inf;
		for(tail=0; tail<k; tail++)
		{
			if(!book[b[tail]]) sum++;
			book[b[tail]]++;
			while(sum==sum1)
			{
				min1=min(min1,tail-head+1);
				book[b[head]]--;
				if(!book[b[head]])
					sum--;
				head++;

			}
		}
		printf("%d\n",min1);
	}
	return 0;
}

 

Source
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值