----------------------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