----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
六、最长公共子序列
描述
咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
输入
第一行给出一个整数N(0<N<100)表示待测数据组数
接下来每组数据两行,分别为待测的两组字符串。每个字符串长度不大于1000.
输出
每组测试数据输出一个整数,表示最长公共子序列长度。每组结果占一行。
样例输入
2
asdf
adfsd
123abc
abc123abc
样例输出
3
6
程序示例:
#include <stdio.h> #include <string.h> char s1[1001], s2[1001]; int dp[1001], t, old, tmp; int main(){ scanf("%d", &t); getchar(); while(t--){ gets(s1); gets(s2); memset(dp, 0, sizeof(dp)); int lenS1=strlen(s1), lenS2=strlen(s2); for(int i=0; i<lenS1; i++){ old=0; //若s1[i]==s2[j],dp[i][j] = dp[i-1][j-1]+1 //否则,dp[i][j] =max(dp[i-1][j], dp[i][j-1]) //此处进行了空间优化,old 代表 dp[i-1][j-1] //dp[j-1] 代表 dp[i][j-1],dp[j] 代表 dp[i-1][j] for(int j=0; j<lenS2; j++){ tmp = dp[j]; if(s1[i]==s2[j]) dp[j] = old+1; else if(dp[j-1]>dp[j])dp[j]=dp[j-1]; old = tmp; } } printf("%d\n", dp[lenS2-1]); } return 0; }
七、回文字符串
描述
所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。
输入
第一行给出整数N(0<N<100)
接下来的N行,每行一个字符串,每个字符串长度不超过1000.
输出
每行输出所需添加的最少字符数
样例输入
1
Ab3bd
样例输出
2
程序示例:
#include"stdio.h" #include"string.h" int a[1001][1001]; int main(){ intT,i,j,len; chars[1001]; scanf("%d",&T); while(T--){ scanf("%s",s); len=strlen(s); memset(a,0,sizeof(a)); for(i=1;i<=len;i++) for(j=1;j<=len;j++){ if(s[i-1]==s[len-j]) a[i][j]=a[i-1][j-1]+1; elseif(a[i-1][j]>a[i][j-1]) a[i][j]=a[i-1][j]; elsea[i][j]=a[i][j-1]; } printf("%d\n",len-a[len][len]); } return0; }
八、单调递增子序列(二)
描述
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
输入
有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列*有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束。
输入数据保证合法(全为int型整数)!
输出
对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
样例输入
7
1 9 10 5 11 2 13
2
2 -1
样例输出
5
1
程序示例:
#include"stdio.h" int a[100001]; int main(){ inti,j,n,m,k; while(scanf("%d",&n)!=EOF){ scanf("%d",&a[0]); k=0; for(i=1;i<n;i++){ scanf("%d",&m); if(m<a[0]){ a[0]=m; }elseif(m>a[k]){ a[++k]=m; }else{ for(j=1;j<=k;j++){ if(m<a[j]&&m>a[j-1]){ a[j]=m; break; }elseif(m<a[j]) break; } } } printf("%d\n",k+1); } return0; }
九、喷水装置(一)
描述
现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。
输入
第一行m表示有m组测试数据
每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。
输出
输出所用装置的个数
样例输入
2
5
2 3.2 4 4.5 6
10
1 2 3 1 2 1.2 3 1.1 1 2
样例输出
2
5
程序示例:
#include"stdio.h" #include"math.h" #include"stdlib.h" int main() { inti,j,n,m,a,b,k,*q; doublet,sum,*p[10],s[600]; scanf("%d",&n); q=(int*)malloc(sizeof(int)*n); for(i=0;i<n;i++){ scanf("%d",&m); p[i]=(double*)malloc(sizeof(double)*m); for(j=0;j<m;j++) scanf("%lf",s+j); p[i]=s; for(a=0;a<m-1;a++) for(b=a+1;b<m;b++) if(*(p[i]+a)<*(p[i]+b)){ t=*(p[i]+a); *(p[i]+a)=*(p[i]+b); *(p[i]+b)=t; } sum=0.0; for(k=0;k<m;k++){ if(sum<20) sum+=2*sqrt(pow(*(p[i]+k),2)-1); else break; } q[i]=k; } for(i=0;i<n;i++) printf("%d\n",q[i]); return0; }
十、喷水装置(二)
描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2
程序示例:
#include"stdio.h" #include"math.h" #include"stdlib.h" struct pen{ int l; int r; }; int main() { struct pen a[10001]; inti,j,k,count,T; int x,r,min,max,w,h,n,imax; scanf("%d",&T); while(T--){ j=0; scanf("%d%d%d",&n,&w,&h); for(i=0;i<n;i++){ scanf("%d%d",&x,&r); if(r>h/2.0){ a[j].l=x-sqrt(r*r-h/2.0*h/2.0); if(a[j].l<0) a[j].l=0; a[j++].r=x+sqrt(r*r-h/2.0*h/2.0); if(a[j-1].r>w) a[j-1].r=w; } } for(i=0;i<j-1;i++) for(k=i+1;k<j;k++) if(a[i].l>a[k].l){ min=a[i].l;a[i].l=a[k].l; a[k].l=min; min=a[i].r;a[i].r=a[k].r; a[k].r=min;} count=0; if(a[0].l!=0||j==0) count=0; elseif(a[0].r==w) count=1; else{ max=0; for(i=0;i<j;i++){ imax=0; for(k=i;k<j;k++){ if(a[k].l<=max&&a[k].r>imax){ imax=a[k].r; } if(a[k].l>max){ i=k-1;break; } } max=imax; if(max==0){ count=0; break; } elseif(max==w){ count++;break; } else{ count++; } } if(max!=w) count=0; } printf("%d\n",count); } return0; }
----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
详细请查看:www.itheima.com