入门OJ 1531【士兵训练】

描述

N个士兵排成一队进行军事训练,每个士兵的等级用1...K范围内的数来表示,
  长官每隔1小时就随便说出M个等级a1,a2…am(1≤ai≤K,M个等级中允许有重复),
  如果这M个等级组成的序列是排成一队的N个士兵等级序列的子序列,
  那么训练继续;否则训练结束。长官想知道,M至少为多少时,训练才有可能结束。
  例:士兵等级序列为1 5 3 2 5 1 3 4 4 2 5 1 2 3,
  长官说出的等级序列为5 4,那么训练继续,
  如果长官说出的等级序列为4 4 4,那么训练结束。

输入输出格式

输入

第一行为两个整数N和K(1≤N≤100000,1≤K≤10000),下面N行,每行一个数,按队伍顺序表示每个士兵的等级。

输出

包括一行,只包含一个数M,表示当长官至少说出M个等级的时候,训练才有可能结束。

输入输出样例

输入样例

14 5
1
5
3
2
5
1
3
4
4
2
5
1
2
3

输出样例

3

解题思路

  首先,我以为这是一道水题,找等级数量最少的就行,然后WA。原来,他要求是子序列(度娘会告诉你的)。然后我就改了改代码。我们把这一列士兵分成几部分,使得每一部分都有所有的等级并且最短,然后只需要把分成的部分的数量加1就可以结束训练了

  可能还是有点蒙,我们是取极端情况,取每一部分最后一个数,这个数在这一部分只出现了一次,就不会担心子序列连到前面,一直这么连,就求到了最长中最短的情况,再加一就找不到了。

题解

 1 #include
 2 using namespace std;
 3 int n,m,k,ans;
 4 int a[100001],c[100001];
 5 int read()//好用的快读 
 6 {
 7     int x=0,f=1;
 8     char ch=getchar();
 9     while(ch<'0'||ch>'9'){
10         if(ch=='-')
11             f=-1;
12         ch=getchar();
13     }
14     while(ch>='0'&&ch<='9'){
15         x=(x<<1)+(x<<3)+(ch^48);
16         ch=getchar();
17     }
18     return x*f;
19 }
20 int main()
21 {
22     cin>>n>>m;
23     for(int i=1;i<=n;i++)
24         a[i]=read();//输入士兵 
25     for(int i=1;i<=n;i++)
26     {
27         if(c[a[i]]==ans)
28         {
29             c[a[i]]++;
30             k++;//等级数 
31         }
32         if(k==m)
33         {
34             ans++;//部分的数量 
35             k=0;
36         }
37     }
38     cout<1;//加一输出 
39     return 0;
40 }

 

转载于:https://www.cnblogs.com/hualian/p/11184864.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部