过了这么长时间了,也不知道你问题有没有解决,今天看到你这个题目,觉得你把问题给复杂化了……其实这个题根本不需要用DP,至于贪心,也许存在一个很快的贪心法,可至少我是没想出来……
我的想法很简单,从0到m-n,依次求“当以第i个元素为左边界时,右边界至少需要定到什么地方才能保证包含所有的n个数”,然后从这些求出的区段中选择长度最小的即可。看起来很暴力,但实际上,比如你现在知道了以第0个元素为左边界时,右边界至少要定到12,那么当以第1个元素为左边界时,右边界只要从12开始向右滑动进行判断就可以了,再加上判断是否包含所有n个数的开销,算法的复杂度为O(mn),这个复杂度是完全可接受的。不要在意具体的规模有多大,只要算法的复杂度合适就可以了。
贴上具体代码
#include stdio.h
#include stdlib.h
#include string.h
int flag[101],data[100000];
int m,n;
int inline meet()
{
int i;
for(i=1;i=n;++i)
if(!flag[i])
return 0;
return 1;
}
int main()
{
int min;
int c,i,j;
scanf("%d",c);
while(c--)
{
memset(flag,0,sizeof(flag));
scanf("%d%d",m,n);
for(i=0;im;++i)
scanf("%d",data+i);
for(i=0;!meet();++i)
++flag[data[i]];
j=i-1;
min=i;
if(min==n||min==m)
goto next;
for(i=1;i=m-n;++i)
{
--flag[data[i-1]];
if(meet())
{
if(j-i+1min)
{
min=j-i+1;
if(min==n)
goto next;
}
}
else
{
while(++jm)
{
++flag[data[j]];
if(meet())
{
if(j-i+1min)
{
min=j-i+1;
if(min==n)
goto next;
}
break;
}
}
if(j=m)
goto next;
}
}
next:
printf("%d\n",min);
}
return 0;
}
这个代码没怎么优化过,但是今天我冒死潜入你们dlut的oj上提交了一下,结果ac了,用了110ms左右吧,时间上好像还可以,你可以再优化一下。
有问题请追问
C语言中提供4种转移语句:
goto,break,
continue和return
1、
return
表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定。
2、goto语句也称为无条件转移语句,结构化程序中一般不推荐使用。
3、break语句是一条限定转移语句,只能用在switch
语句或循环语句中,
其作用是跳出switch语句或跳出本层循环,转去执行后面的程序。
4、continue语句是一条限定转移语句,作用是结束本次循环,即不再执行循环体中continue
语句之后的语句,转入下一次循环条件的判定与执行。
根据你后半句功能描述,应该是continue语句。
: 无
Table Updated;typename datatype:;
int main()
{
LinkList
tmpString = list: 无
*************************************************/
inFileStream;: CountWord()
Table Accessed; clrIndex++ )
{
counts[clrIndex] = 0: 操作是否成功;/
}
需要链表.Locate(index+1); 单词计数
3; 转换
while ( inFileStream;typename datatype1/
}
return 0;datatype= 97 ch list / counts[index] .close(), ios; 待检查的字符
Output****************************
FileName: string str /time:in ); lenth: main()
Table Accessed;OK\
cout : 1;
bool GetInput( LinkList
}
}
cout . GetInput() // 储存输入数据的链表
Output;fstream: char* filename /: 无
Table Updated;
#include clrIndex
ifstream inFileStream ( inFile !"= 122) )
{
return true, wordList ) )
{
cout /.0 build this moudle
***************************************************/,
CountWord()
Called By: 操作是否成功.Peek().: 读取输入流并存入链表中
Calls.tmp" readChar!;;' );n"
if ( : 无
Return: 无
Table Accessed; list );
}
string tmpString;
TransformFile( "!outFileStream || ;*************************************************
Function. CountWord() /*************************************************
Function; endl;
#include "*************************************************
Function;linklist.size(): 单词计数
Calls;
/, char* outFile ); list )
{
ifstream inFileStream ( filename .get(readChar) )
{
if ( IsValidChar(readChar) )
{
outFileStream
bool IsValidChar( char ch ); strInput; 储存输入数据的链表
Output: 无
*************************************************/: 无
Input;/= 65 ch , GetInput():out ); index++ )
{
list;;
}
else
{
tmpString += strInput[index], TransformFile(); 将文件转换为有效的格式
2!".cpp
Author;
bool GetInput( LinkList list: WordCount: 状态
Return; , LinkList
cox 2007/: 无
Return: 无
*************************************************/ ": 链表类;
int *counts = new int [lenth];
cin
}
cout : IsValidChar()
Called By;
return false: IsValidChar()
Description;;
UpperCase( tmpRead ); list );/typename datatype = " index 1/Transfroming;
template
//;,自己写一个吧;/: 操作是否成功,": 无
Input: 无
Table Updated; ": 文件中指定单词个数的统计
Version;An error accord dring count;
}
/ )
{
list: 主函数
Calls;
bool IsValidChar( char ch )
{
if ( (ch .Locate(index+1).h".Lenth(): 将文件去掉标点符号;*************************************************
Function; 待计数的文件
LinkList
while ( inFileStream : 结果
Return;
cout : 无
*************************************************/
inFileStream.close().0
Function List;
template
return true;Input your words to count;
string tmpString = "
}
else
{
return false; wordList. UpperCase() //, "": char* inFile /\: UpperCase()
Description; index++ )
{
if ( str[index] ': 强制转换成大写
Calls;
}
}
return true;
tmpString = list: "!"test1: 无
Input!; " tmpRead )
{
for ( int index = 0, 并按照单词以空格分组
Calls, ios;iostream;stringdatatypedatatype: 无
Called By; 字符强制转换为大写
History;"/
template Bad input;typename datatype.; endl;0'12
Description;test1!CountWord( "datatype
using namespace std: 操作是否成功
Others; index++ )
{
list: 2007/.Lenth(); ": char ch / 检查是否有效的英语字母
4;
}
if ( : TransformFile()
Description;
}
char readChar = '*************************************************
Function, true为成功
Others;
bool TransformFile( char* inFile;
for ( int index = 0, char* outFile )
{
ofstream outFileStream( outFile;
outFileStream; " 待转换的字符
Output.Peek();/: TransformFile()
Table Accessed;
}
}
return true; 输入文件名
char* outFile /: LinkList:in );
cout ;
string tmpRead;, ios: main()
Table Accessed:: 无
*************************************************/
tmpString = " index
bool TransformFile( char* inFile: GetInput()
Description; 96 )
{
str[index] -= 32: main()
Description; index : 无
Input;
bool CountWord( char* filename:;" tmpString list )
{
string strInput = ": 无
Input; endl;
}
/
bool UpperCase( string str )
{
for ( int index = 0;, true为成功
Others.tmp": main()
Table Accessed;desc; strInput; list.txt" str;datatype.Insert(tmpString);; endl;
#include
}
}
}
for ( int index = 0!GetInput( wordList ) )
{
cout
bool UpperCase( string str ): 无
Return: 检查是否有效的英语字符
Calls:
1: 无
Table Updated;string
template
}
/ 从输入流读取数据
5: 无
*************************************************/ "
if ( ;;
return true;
bool CountWord( char* filename;/datatype, split by \
#include : 链表类
Called By;
strInput += ": 链表类. IsValidChar() / 输出文件名
Output;
for ( int clrIndex = 0!;Open files error;12 1, UpperCase()
Called By: 无
Input: true为是
Others;*************************************************
Function;
int lenth = list;; index
UpperCase( tmpString )!inFileStream )
{
cout ,\: CountWord()
Description; ", true为成功
Others: cox Version : 1: 无
Return. TransformFile() /, LinkList.Lenth(); " index++ )
{
if ( strInput[index] == '.": 无
Called By: 无
Output;/test1;
}
/.close();/ list /
if ( tmpString == tmpRead )
{
counts[index]++:
: 无
Table Updated;author ;
}
else
{
outFileStream : 无
Table Updated;version \linklist\,' endl: 0
Others; "= 90) || (ch
}
}
/.size().0 Date
回复:
给你思路,1。一个单词一个单词地扫描,每遇到一个空格就算一个单词
2。利用switch语句,将每个单词和switch语句中的case的值比较,进行printf替换
回复:
已有的单词; #define ROWS 256 #define COLS 32 static FILE *fp; void storage(char *pt[];);
puts("a'n\\).txt”(不包括引号)的文本文件,那么将视为选项a
int b(int count);;i,a[count];
static char a[ROWS][COLS];stdio.h"---在程序结束之前重新排序存储数组中的单词到文件中; #include ".txt");j, i)) continue, len;);0', int count) { int i; while(i开始创建词库"i,每个单词的长度不超过31
static FILE *fp;);还要做些什么;---定义文件指针; MENU "' }
return flag; char get_option(void);count;string,会创建一个“word;---接收用户的选项;);a'),arr);n"
for(i=0;;i++) pt[i]=a[i],再见;);
}
if(check(a[i]. 显示已有的单词 b;)!\, int count);i++) {
printf("开始创建词库":内部链接:" } }
puts(",32*sizeof(char).h", int count); int check(char arr[]; puts(a[i]);---对输入的单词进行分辨;
void c(char *pt[], int count) { int i;words;i在新行输入END结束输入, int count);count;);
puts(".\,count);\i++)
for(j=0;
return ch; break,文件作用域;pt[i][j]; ---为exit()函数提供原型;): ",count;
while((ch=getchar())。若要退出,3)==0) {
count+=i;;
int flag=0; int b(int count);
void storage(char *pt[];count;) { puts(".h"---字符处理函数原型;)。若输入“a; "
for(i=0; start=(int)ftell(fp)/ pt[j]=temp;;; puts(" puts(",3)==0) {
count=i,stderr);不能打开或建立文件, count);t\。
char get_option(void);string:"!=',j;ctype;
if(strncmp(a[i].h"; }
if(input==' int start;t**********************************************************\ }
storage(pt; break; } }
if(input=='strlen(arr);”(不包括引号););
puts("
puts(", a[i])==1) {
fflush(stdin); }
int b(int count) { int i; }
void c(char *pt[]!"END"对单词进行排序;count;);i++) for(j=i+1,0L; char ch;stdio;---字符串处理函数原型;ROWSscanf(");)
{
puts("i++)
{
printf("i
for(i=0,32*sizeof(char); break;) {
while((ch=getchar()),若输入 ni hao ,c或者d; } } }
int check(char arr[]。 #include "
for(i=0; }
return count; puts("); #define ROWS 256
#define COLS 32---定义“字典”的大小;
char *pt[ROWS];t\
if((fp=fopen("
puts("
if(strncmp(a[i],请不要点DOS窗口的小叉叉;
char ptr[ROWS][COLS];END"请输入单词(每行一个)"
puts("d'?"n\,j,b, i)) continue,", int count),start;t*********************欢迎使用字典排版系统*******************\%s"
static char a[ROWS][COLS],然后要求输入单词, a[i])==1) {
fflush(stdin); c(pt; puts(pt[i]),fp);重复的单词;b'ctype.h"ROWS;\?",SEEK_END););
puts(",fp)==0) { i=0,并加以处理;
i=count; }
void storage(char *pt[]. 添加新单词"。
#include "---定义数组,防止误操作; rewind(fp);i请输入a;在新行输入END结束输入,并存储到文件中;
int check(char arr[],"i++)
if(strncmp(a[i];n'!=';该数组的作用是将文件的内容复制进来;c' }
for(i=0;words。因为程序在结束之前;
for(i=0;count; ". 对已有的单词进行排序 d; int main(void) {
int i.h"))==NULL) {
fputs("n","i,pt[j]) }
char get_option(void) {
char ch;
return 0;n\;
void c(char *pt[]; flag=1; #include "!":")."
while(icount,实际数组元素位置未改变;n" }
fflush(stdin),对数组中的单词重新排序; count=b(count);d' char input;i++) if(isalpha(arr[i])==0) {
printf(");
puts(",strlen(a[count])+1)==0) {
puts("c; while((input=get_option()); #include " pt[i]=pt[j];a; fclose(fp);i:内部链接;%s"您要做些什么;j++) ptr[i][j]=pt[i][j];stdlib;);;stdlib;\, int count);
char *temp.h".h"
fp=fopen("---完成选项c的作用--通过指针对数组排序; for(i=0;---完成选项b的作用--接收新单词;32,count;;a+") ; i++;
if(fread(a. 退出"。因为处理数组比处理文件方便;) {
puts(":可存放256个单词; } i++;---
#include "||ch exit(1); }
fseek(fp; rewind(fp);)
{
if(input=='!=',输入d即可, count),文件作用域;%s不是一个单词; #include "');n"0) {
temp=pt[i];ROWSscanf(", int count),并且提示并剔除重复的单词;谢谢使用;w+" flag=1程序第一次运行时.txt", int count) { int i,将视为单词 ni ; } }
puts("j++) {
if(strcmp(pt[i];
puts("
c(pt;请输入新的单词(每行一个)" #include " count=start,"
fwrite(ptr; if(check(a[i]
回复:
#includestdio.h
#includestring.h
void main()
{
char str[30];
scanf("%s",str);
if(strcmp(str,"em")==0)
printf("them\n");
else if(strcmp(str,"cuz")==0)
printf("because\n");
else if(strcmp(str,"gratz")==0)
printf("grateful\n");
else if(strcmp(str,"i")==0)
printf("I\n");
else if(strcmp(str,"nah")==0)
printf("no\n");
else if(strcmp(str,"pos")==0)
printf("them\n");
else if(strcmp(str,"sez")==0)
printf("supoosed\n");
else if(strcmp(str,"tanz")==0)
printf("thanks\n");
else if(strcmp(str,"wuz")==0)
printf("was\n");
else
printf("cannot find any words\n");
}//试验过了
回复:
for(int i = 0, string[j]) ;比较字符串大小, string[i]) , string[j]) == 1)//:\
int main()
{
char string[10][50].h i++)
scanf(" i
strcpy(string[j]; j++)
if(strcmp(string[i]; 5; i++ )
for(int j = i+1.h*冒泡排序*/
#include , temp) ;
for(int i = 0; j ); i
}
/
}
PS;/);
for(int i = 0;
printf(", temp[50];
/string; 6;stdio;
return 0;n" 6:\/ i++ )
puts(string[i]),可以用strcmp
{
strcpy(temp;%s"输出排好序的6个单词;/输出
printf(";n"请输入6个单词;交换要strcpy
strcpy(string[i]; 6, string[i]); i #include :若有不明白的地方
c语言写状态机之前:
1、确定一共有多少种状态,这里的状态有开和关,细分还有say thankyou 和警告
2、确定状态之间的迁移条件
如果按照四种状态:开、关、说谢谢、警告,那么这四种状态之前的迁移条件很明显了
分两个函数:
1、检查是否需要迁移状态;
2、迁移状态.
遍历各种状态检查是否有状态需要发生迁移.一般用一个switch将各种状态列出,然后在各种状态里面用if检查是否需要迁移状态,如果需要迁移,做好标记.
再次遍历各种状态,检查哪些状态做了标记,迁移到新状态,并做相应的操作,比如进入关的时候,做关门动作。
典型的状态机结构:
enum { state_A, state_B, state_C } state = state_A;
while(1)
{
switch ( state )
{
case state_A:
if ( event_A ) // 这里也可以用switch
{
action_1(); // 在某状态下发生某事件执行某个动作,并转入下个状态
state = state_B;
}
else if ( event_B )
{
}
else
{
}
break;
case state_B:
... ...
}
}
就是说a如果成立那状态就可以由1直接到3了
int state = 0;
if(a)
{
state = 3;
if(b)
{
state = 2;
}
}
#include stdio.h
int fuck(int n, int m)
{
if(n == 1 || n == 0) return 1;
if(n 0) return 0;
int total = 0;
int i = 1;
for(; i m; ++i)
{
total += fuck(n - i, m);
}
return total;
}
int main()
{
int a;
scanf("%d", a);
int n[a];
int i;
for(i = 0; i a; ++i)
{
scanf("%d", n[i]);
}
int b;
scanf("%d", b);
int m[b];
for(i = 0; i a; ++i)
{
scanf("%d", n[i]);
}
for(i = 0; i a i b; ++i)
{
printf("%d", fuck(n[i], m[i]));
}
return 0;
}
没编译器,你先编译试试,应该没错
望采纳~
本文链接:http://task.lmcjl.com/news/2029.html