mirror of
https://github.com/m1ngsama/code4sk.git
synced 2025-12-24 10:51:22 +00:00
Delete c/sourcecode/AlgorithmO/20230911 directory
This commit is contained in:
parent
f20c1a56c8
commit
367565b051
12 changed files with 0 additions and 825 deletions
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
E. Toocold之区间最大子段和
|
||||
Description
|
||||
Toocold学会了怎样求区间最大子段和,现在他又玩出了新花样.他有n个数,他想知道对于区间的左端点l限定在[ll,rr]之间, 对于区间的右端点r限定在[ll2,rr2]之间的区间最大和是多少?
|
||||
|
||||
Input
|
||||
输入第一行cas(1<=cas<=10)表示有几个cas
|
||||
|
||||
接下来每个cas的第一行是一个数n(1<=n<=100000)表示有n个数
|
||||
|
||||
第二行有n个数,a1,a2,a3...an(-1000<=ai<=1000)
|
||||
|
||||
第三行一个数q(1<=q<=100000)表示有q个询问
|
||||
|
||||
接下来q行每行四个数字ll, rr, ll2, rr2.(1<=ll,rr,ll2,rr2<=n)(ll<=rr)(ll2<=rr2)(rr2>=ll)表示左端点l的范围和右端点r的范围
|
||||
|
||||
Output
|
||||
每个询问输出符合范围的区间最大和
|
||||
|
||||
Sample Input
|
||||
1
|
||||
6
|
||||
4 -3 1 -3 5 -2
|
||||
2
|
||||
1 4 2 5
|
||||
1 1 3 4
|
||||
Sample Output
|
||||
4
|
||||
2
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int MAXN=100015;
|
||||
int n,m;
|
||||
int a[MAXN],pre_sum[MAXN],suf_sum[MAXN],l1,l2,r1,r2;
|
||||
struct tnode
|
||||
{
|
||||
int sum,lmax,rmax,ans;
|
||||
int l,r;
|
||||
};
|
||||
tnode operator + (const tnode& a,const tnode& b)
|
||||
{
|
||||
tnode c;
|
||||
c.l=a.l;
|
||||
c.r=b.r;
|
||||
c.sum=a.sum+b.sum;
|
||||
c.lmax=max(a.lmax,a.sum+b.lmax);
|
||||
c.rmax=max(a.rmax+b.sum,b.rmax);
|
||||
c.ans=max(a.ans,b.ans);
|
||||
c.ans=max(c.ans,a.rmax+b.lmax);
|
||||
return c;
|
||||
}
|
||||
struct Segment_Tree
|
||||
{
|
||||
tnode t[4*MAXN];
|
||||
void update(int root)
|
||||
{
|
||||
int ch=root<<1;
|
||||
t[root]=t[ch]+t[ch+1];
|
||||
}
|
||||
void buildt(int root,int l,int r,int A[])
|
||||
{
|
||||
if(l!=r)
|
||||
{
|
||||
int mid=(l+r)>>1;
|
||||
int ch=root<<1;
|
||||
buildt(ch,l,mid,A);
|
||||
buildt(ch+1,mid+1,r,A);
|
||||
update(root);
|
||||
}
|
||||
else
|
||||
{
|
||||
t[root].ans=t[root].lmax=t[root].rmax=t[root].sum=A[l];
|
||||
t[root].l=t[root].r=l;
|
||||
}
|
||||
}
|
||||
tnode query(int root,int l,int r)
|
||||
{
|
||||
if(t[root].l==l&&t[root].r==r)
|
||||
{
|
||||
return t[root];
|
||||
}
|
||||
int mid=(t[root].l+t[root].r)>>1;
|
||||
int ch=root<<1;
|
||||
if(r<=mid)return query(ch,l,r);
|
||||
else if(l>mid)return query(ch+1,l,r);
|
||||
else return query(ch,l,mid)+query(ch+1,mid+1,r);
|
||||
}
|
||||
};
|
||||
Segment_Tree ST1;
|
||||
struct tnodes
|
||||
{
|
||||
int Max;
|
||||
int l,r;
|
||||
};
|
||||
struct Segment_Tree_Max
|
||||
{
|
||||
tnodes t[4*MAXN];
|
||||
void buildt(int root,int l,int r,int A[])
|
||||
{
|
||||
t[root].l=l;
|
||||
t[root].r=r;
|
||||
if(l!=r)
|
||||
{
|
||||
int mid=(l+r)>>1;
|
||||
int ch=root<<1;
|
||||
buildt(ch,l,mid,A);
|
||||
buildt(ch+1,mid+1,r,A);
|
||||
t[root].Max=max(t[ch].Max,t[ch+1].Max);
|
||||
}
|
||||
else t[root].Max=A[l];
|
||||
}
|
||||
int query(int root,int l,int r)
|
||||
{
|
||||
if(t[root].l==l&&t[root].r==r)
|
||||
{
|
||||
return t[root].Max;
|
||||
}
|
||||
int mid=(t[root].l+t[root].r)>>1;
|
||||
int ch=root<<1;
|
||||
if(r<=mid)return query(ch,l,r);
|
||||
else if(l>mid)return query(ch+1,l,r);
|
||||
else return max(query(ch,l,mid),query(ch+1,mid+1,r));
|
||||
}
|
||||
};
|
||||
Segment_Tree_Max ST2,ST3;
|
||||
int get_sum(int l,int r)
|
||||
{
|
||||
if(l>r)return 0;
|
||||
return pre_sum[r]-pre_sum[l-1];
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int T;
|
||||
scanf("%d",&T);
|
||||
while(T--)
|
||||
{
|
||||
scanf("%d",&n);
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
}
|
||||
ST1.buildt(1,1,n,a);
|
||||
pre_sum[0]=suf_sum[n+1]=0;
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
pre_sum[i]=pre_sum[i-1]+a[i];
|
||||
}
|
||||
for(int i=n;i;--i)
|
||||
{
|
||||
suf_sum[i]=suf_sum[i+1]+a[i];
|
||||
}
|
||||
ST2.buildt(1,1,n,pre_sum);
|
||||
ST3.buildt(1,1,n,suf_sum);
|
||||
scanf("%d",&m);
|
||||
while(m--)
|
||||
{
|
||||
scanf("%d %d %d %d",&l1,&r1,&l2,&r2);
|
||||
if(r1<l2)///3 无交
|
||||
{
|
||||
printf("%d\n",ST3.query(1,l1,r1)-pre_sum[n]+ST2.query(1,l2,r2));
|
||||
}
|
||||
else if(l2<=l1&&l1<=r2&&r2<=r1)///2
|
||||
{
|
||||
printf("%d\n",ST1.query(1,l1,r2).ans);
|
||||
}
|
||||
else if(l1<=l2&&l2<=r1&&r1<=r2)///1
|
||||
{
|
||||
int temp=ST1.query(1,l2,r1).ans;
|
||||
if(l2-1>=l1)
|
||||
{
|
||||
temp=max(temp,ST3.query(1,l1,l2-1)-pre_sum[n]+ST2.query(1,l2,r2));
|
||||
}
|
||||
if(r1+1<=r2)
|
||||
{
|
||||
temp=max(temp,ST2.query(1,r1+1,r2)-pre_sum[n]+ST3.query(1,l1,r1));
|
||||
}
|
||||
printf("%d\n",temp);
|
||||
}
|
||||
else if(l1<=l2&&l2<=r2&&r2<=r1)///4
|
||||
{
|
||||
int temp=ST1.query(1,l2,r2).ans;
|
||||
if(l2-1>=l1)
|
||||
{
|
||||
temp=max(temp,ST3.query(1,l1,l2-1)-pre_sum[n]+ST2.query(1,l2,r2));
|
||||
}
|
||||
printf("%d\n",temp);
|
||||
}
|
||||
else if(l2<=l1&&l1<=r1&&r1<=r2)///5
|
||||
{
|
||||
int temp=ST1.query(1,l1,r1).ans;
|
||||
if(r1+1<=r2)
|
||||
{
|
||||
temp=max(temp,ST2.query(1,r1+1,r2)-pre_sum[n]+ST3.query(1,l1,r1));
|
||||
}
|
||||
printf("%d\n",temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
C. 公共交通问题
|
||||
Description
|
||||
现在的大学生刚毕业不久如果没有家庭的支持一般是买不起心仪的车的,所以刚毕业的人一般都要乘公交车上下班,在早晚的上下班高峰时间段,道路交通很拥挤,每站都有人上下,公交车在每站都停。刚刚毕业的小明常常会被每站都停的公交车弄得很不耐烦,于是他提出了这样一个办法:
|
||||
|
||||
由于公交车的站点并不是非常多,那么在繁忙的上下班高峰时间,每次公交车从始发站点往终点站点开时,我们只允许公交车停在其中的某一个站点。所有乘客都从始发站点上公交车,到达某站点后,公交车停下来,所有乘客再从这里步行到自己的目的站点。在始发站的时候,每个乘客选择自己的目的站点,公交车系统则自动计算出应停的站点。
|
||||
|
||||
现在请问:公交车停在哪一站点能够保证这次乘坐公交车的所有乘客步行的站点数之和最少?
|
||||
|
||||
在这里为了更好体现算法的魅力所在,我们假定站点数可以很多,每次乘客人数也可以很多(实际生活中这两点是不可能出现的)。另外为了方便起见,在这里我们规定,刚开始公交车在始发站,并且认为乘客至少是在第一个站点及以后才有可能下车。
|
||||
|
||||
Input
|
||||
有两行,第一行是公交站点数N(1<=N<=1000),第二行是N个正整数,分别表示对应站点(以该站点作为目的站点)的乘客人数M(1<=M<=1000)。
|
||||
|
||||
Output
|
||||
只有一行,输出两个正整数,第一个是计算出来的公交车停靠的站点,第二个是所有乘客需要步行的站点总数,中间有一个空格。如果公交车在不同站点停车都可以让乘客步行站点最少的话,则公交车会停在最先到达的站点,这样可以省些油和时间。
|
||||
|
||||
本问题有多组测试数据。
|
||||
|
||||
Sample Input
|
||||
5
|
||||
14 12 2 18 15
|
||||
6
|
||||
4 9 0 16 16 12
|
||||
Sample Output
|
||||
4 83
|
||||
4 70
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long ll;
|
||||
int a[1010];
|
||||
int main()
|
||||
{
|
||||
int n;
|
||||
while(cin>>n)
|
||||
{
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
}
|
||||
int ans=INT_MAX;
|
||||
int pos=0;
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
int cnt=0;
|
||||
for(int j=1;j<=n;j++)
|
||||
{
|
||||
cnt+=a[j]*(abs(j-i));
|
||||
}
|
||||
if(cnt<ans)
|
||||
{
|
||||
ans=cnt;
|
||||
pos=i;
|
||||
}
|
||||
}
|
||||
cout<<pos<<' '<<ans<<endl;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
G. 数列游戏
|
||||
Description
|
||||
小明最近为了锻炼智力,在玩一个数列求和的游戏。设数列的长度为 n,每一个数字都是整数,且在[-1000,1000]范围内,即范围是 -1000~1000。
|
||||
|
||||
游戏规则:小明可以从这个数列里面选一串任意长度的连续子串并求和,小明想知道子串和绝对值的最大值是多少,你能帮帮他吗?
|
||||
|
||||
绝对值:正数的绝对值为本身,负数的绝对值为它的相反数。
|
||||
|
||||
如 5 的绝对值为 5,-7 的绝对值为 7 。
|
||||
|
||||
Input
|
||||
输入共两行,第一行为一个整数 n,第二行为 n 个整数。
|
||||
|
||||
Output
|
||||
输出一个数,为数列子串和绝对值的最大值。
|
||||
|
||||
Sample Input
|
||||
样例一:
|
||||
10
|
||||
-562 232 969 201 -111 378 -610 127 245 932
|
||||
样例二:
|
||||
10
|
||||
868 -838 -958 200 867 -920 -493 114 -800 757
|
||||
样例三:
|
||||
10
|
||||
-607 -260 -270 -833 560 -280 404 -542 560 -115
|
||||
Sample Output
|
||||
样例一:
|
||||
2363
|
||||
样例二:
|
||||
2828
|
||||
样例三:
|
||||
1970
|
||||
Hint
|
||||
对于样例 1,可以发现 232+969+201-111+378-610+127+245+932=2363 所以2363 是最大的绝对值。
|
||||
|
||||
对于样例 2,可以发现 -838+-958+200+867+-920+-493+114+-800= -2828 所以 2828 是最大的绝对值。
|
||||
|
||||
对于 20% 的数据,满足 n<=10
|
||||
|
||||
对于 50% 的数据,满足 n<=100
|
||||
|
||||
对于 70% 的数据,满足 n<=1000
|
||||
|
||||
对于 100% 的数据,满足 n<=1000000
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int MAXN=1000005;
|
||||
const long long inf=(1LL<<60);
|
||||
int n;
|
||||
long long pre_sum[MAXN],pre_min[MAXN],pre_max[MAXN],ans,a[MAXN];
|
||||
int main()
|
||||
{
|
||||
scanf("%d",&n);
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%lld",&a[i]);
|
||||
pre_sum[i]=pre_sum[i-1]+a[i];
|
||||
}
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
pre_max[i]=max(pre_max[i-1],pre_sum[i-1]);
|
||||
pre_min[i]=min(pre_min[i-1],pre_sum[i-1]);
|
||||
ans=max(ans,abs(pre_sum[i]-pre_min[i]));
|
||||
ans=max(ans,abs(pre_sum[i]-pre_max[i]));
|
||||
}
|
||||
printf("%d\n",ans);
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
Description
|
||||
给出N个数字, 计算出最大的子段和。
|
||||
|
||||
Input
|
||||
第一行给出一个数字 T(1<=T<=20) 代表接下来的组数.
|
||||
接下来每 T 行,开始给出一个正整数 N(1<=N<=100000), 接着跟着N个整数.。数据保证中间结果和最后结果都在int范围内。
|
||||
|
||||
Output
|
||||
输出最大的子段和
|
||||
|
||||
Sample Input
|
||||
2
|
||||
5 6 -1 5 4 -7
|
||||
7 0 6 -1 1 -6 7 -5
|
||||
Sample Output
|
||||
14
|
||||
7
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int MAXN=100005;
|
||||
int n;
|
||||
long long a[MAXN],sum,ansum;
|
||||
pair<int,int>ans;
|
||||
int main()
|
||||
{
|
||||
int T;
|
||||
scanf("%d",&T);
|
||||
while(T--)
|
||||
{
|
||||
scanf("%d",&n);
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
scanf("%lld",&a[i]);
|
||||
}
|
||||
bool flag=false;
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
if(a[i]>=0)flag=true;
|
||||
}
|
||||
if(!flag)
|
||||
{
|
||||
printf("0\n");
|
||||
continue;
|
||||
}
|
||||
int pos=0;
|
||||
ansum=-1;
|
||||
sum=0;
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
sum+=a[i];
|
||||
if(sum<0)
|
||||
{
|
||||
sum=0;
|
||||
pos=i;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(sum>ansum)
|
||||
{
|
||||
ansum=sum;
|
||||
ans=make_pair(pos+1,i);
|
||||
}
|
||||
else if(sum==ansum)
|
||||
{
|
||||
ans=min(ans,make_pair(pos+1,i));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%lld\n",ansum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
C. 最大子段和问题
|
||||
Description
|
||||
给定n个整数(可能为负数)a1,a2,……an。求ai,ai+1,……aj,其中i<=i<=j<=n的子段和的最大值。当所有整数均为负数时我们定义其最大子段和为0(此时From为1,To为n)。例如:当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为a2+a3+a4=20,i=2,j=4(下标从1开始),这个问题我们称之为“最大子段和问题”。
|
||||
|
||||
Input
|
||||
本问题有多组测试数据,每组数据有两行,第一行为n(n<=1000),第二行有n’个整数,数与数之间用空格隔开。
|
||||
|
||||
Output
|
||||
参见样例格式
|
||||
|
||||
Sample Input
|
||||
6
|
||||
-2 11 -4 13 -5 -2
|
||||
Sample Output
|
||||
From=2,To=4
|
||||
MaxSum=20
|
||||
*/
|
||||
#include <stdio.h>
|
||||
int a[1001],n,max,from,to,s;
|
||||
int main()
|
||||
{
|
||||
int i,j,n;
|
||||
while(1==scanf("%d",&n))
|
||||
{
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
}
|
||||
from=1;
|
||||
to=n;
|
||||
max=0;
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
s=0;
|
||||
for(j=i;j<=n;j++)
|
||||
{
|
||||
s+=a[j];
|
||||
if(max<s)
|
||||
{
|
||||
max=s;
|
||||
from=i;
|
||||
to=j;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("From=%d,To=%d\n",from,to);
|
||||
printf("MaxSum=%d\n",max);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
D. 最大子段和问题三(分治法)
|
||||
Description
|
||||
给你n个整数a1,a2,a3……,an,对于1<=i<=j<=n(1<=n<=100000);求ai+ai+1+ai+2+……aj的最大值。如果给定的n个整数都为负数,那么规定最大值为零。
|
||||
|
||||
要求用分治法求解
|
||||
|
||||
Input
|
||||
输入为两行,第一行为整数n,第二行为n个整数。
|
||||
|
||||
Output
|
||||
输出也有两行,第一行为i和j;第二行为最大的子段和的值,格式参见Sample Output。
|
||||
|
||||
Sample Input
|
||||
6
|
||||
2 -5 11 -4 13 -2
|
||||
Sample Output
|
||||
From=3,To=5
|
||||
MaxSum=20
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int MAXN=100005;
|
||||
int n;
|
||||
long long a[MAXN],sum,ansum;
|
||||
pair<int,int>ans;
|
||||
const long long inf=(1LL)<<61;
|
||||
void div_algorithm(int l,int r)
|
||||
{
|
||||
if(l>r)return;
|
||||
int mid=(l+r)>>1;
|
||||
long long lsum=0,rsum=0,lmax=-inf,rmax=-inf;
|
||||
int lpos,rpos;
|
||||
for(int i=mid;i>=l;--i)
|
||||
{
|
||||
lsum+=a[i];
|
||||
if(lmax<lsum)
|
||||
{
|
||||
lmax=lsum;
|
||||
lpos=i;
|
||||
}
|
||||
else if(lmax==lsum)
|
||||
{
|
||||
lpos=i;
|
||||
}
|
||||
}
|
||||
for(int i=mid;i<=r;++i)
|
||||
{
|
||||
rsum+=a[i];
|
||||
if(rmax<rsum)
|
||||
{
|
||||
rmax=rsum;
|
||||
rpos=i;
|
||||
}
|
||||
}
|
||||
if(ansum<lmax+rmax-a[mid])
|
||||
{
|
||||
ansum=lmax+rmax-a[mid];
|
||||
ans=make_pair(lpos,rpos);
|
||||
}
|
||||
else if(ansum==lmax+rmax-a[mid])
|
||||
{
|
||||
ans=min(ans,make_pair(lpos,rpos));
|
||||
}
|
||||
div_algorithm(l,mid-1);
|
||||
div_algorithm(mid+1,r);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
while(scanf("%d",&n)!=EOF)
|
||||
{
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
scanf("%lld",&a[i]);
|
||||
}
|
||||
bool flag=false;
|
||||
for(int i=1;i<=n;++i)
|
||||
{
|
||||
if(a[i]>=0)flag=true;
|
||||
}
|
||||
if(!flag)
|
||||
{
|
||||
printf("From=0,To=0\nMaxSum=0\n");
|
||||
continue;
|
||||
}
|
||||
ansum=-1;
|
||||
sum=0;
|
||||
div_algorithm(1,n);
|
||||
printf("From=%d,To=%d\nMaxSum=%lld\n",ans.first,ans.second,ansum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
A. 最简单的“最大子段和”问题
|
||||
Description
|
||||
给定n个整数(可能为负数)a1,a2,……an。求ai,ai+1,……aj 其中1<=i<=j<=n的子段和的最大值。当所有整数均为负数时我们定义其最大子段和为0。例如:当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为a2+a3+a4=20,i=2,j=4(下标从1开始)这个问题我们称之为“最大子段和问题”。
|
||||
|
||||
在课堂上,我们假定n<=100,今天我们把n的范围规定修改为n<=200,你的任务是设计一个程序解决它。
|
||||
|
||||
Input
|
||||
输入由两行,第一行为n;第二行为n个整数。
|
||||
|
||||
Output
|
||||
输出也有两行,第一行为:“From=xxx,To=xxx”;第二行为:“MaxSum=xxxx”,参见样例。
|
||||
|
||||
Sample Input
|
||||
6
|
||||
-2 11 -4 13 -5 -2
|
||||
Sample Output
|
||||
From=2,To=4
|
||||
MaxSum=20
|
||||
*/
|
||||
#include <stdio.h>
|
||||
int a[1001],n,max,from,to,s;
|
||||
int main()
|
||||
{
|
||||
int i,j,n;
|
||||
while(1==scanf("%d",&n))
|
||||
{
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
}
|
||||
from=1;
|
||||
to=n;
|
||||
max=0;
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
s=0;
|
||||
for(j=i;j<=n;j++)
|
||||
{
|
||||
s+=a[j];
|
||||
if(max<s)
|
||||
{
|
||||
max=s;
|
||||
from=i;
|
||||
to=j;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("From=%d,To=%d\n",from,to);
|
||||
printf("MaxSum=%d\n",max);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
B. 最简单的“最大子段和”问题
|
||||
Description
|
||||
给定n个整数(可能为负数)a1,a2,……an。求ai,ai+1,……aj 其中i<=i<=j<=n的子段和的最大值。当所有整数均为负数时我们定义其最大子段和为0,且初始和终止位置也为0。例如:当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为a2+a3+a4=20,i=2,j=4(下标从1开始)这个问题我们称之为“最大子段和问题”。
|
||||
|
||||
在考试一上,我们假定n<=200,今天我们把n的范围规定修改为n<=2000,你的任务是设计一个程序解决它。
|
||||
|
||||
Input
|
||||
输入由两行,第一行为n;第二行为n个整数。
|
||||
|
||||
Output
|
||||
输出也有两行,第一行为:“From=xxx,To=xxx”;第二行为:“MaxSum=xxxx”,参见样例。
|
||||
|
||||
Sample Input
|
||||
6
|
||||
-2 11 -4 13 -5 -2
|
||||
Sample Output
|
||||
From=2,To=4
|
||||
MaxSum=20
|
||||
*/
|
||||
#include <stdio.h>
|
||||
int a[1001],n,max,from,to,s;
|
||||
int main()
|
||||
{
|
||||
int i,j,n;
|
||||
while(1==scanf("%d",&n))
|
||||
{
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
}
|
||||
from=1;
|
||||
to=n;
|
||||
max=0;
|
||||
for(i=1;i<=n;i++)
|
||||
{
|
||||
s=0;
|
||||
for(j=i;j<=n;j++)
|
||||
{
|
||||
s+=a[j];
|
||||
if(max<s)
|
||||
{
|
||||
max=s;
|
||||
from=i;
|
||||
to=j;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("From=%d,To=%d\n",from,to);
|
||||
printf("MaxSum=%d\n",max);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
'''
|
||||
E. 穿错衣服问题
|
||||
Description
|
||||
SmallBeer曾经当过兵,他常常回忆起刚入伍时的情景。记得那时周末只有一天休息,而且部队规定休息天外出营区只能有三分之一人数,所以大家都很珍惜周末外出的机会,一旦外出肯定要尽情享受一天的乐趣,但部队规定下午五点必须归队,因此大家外出后回来都很匆忙。其中最有意思的是:早上外出前,大家都把军装洗完晾好,下午归队时赶紧穿上,但由于时间紧,常常发生穿错衣服的事件,现在请你这个编程高手想办法算算,所有人都穿错的情况有多少种?
|
||||
|
||||
Input
|
||||
有多组测试数据,对于每一组测试数据,输入只有一行,即总人数n(1<=n<=1000)。
|
||||
|
||||
Output
|
||||
对于每一组的输入,输出只有一行,即所有人都穿错的情况数。
|
||||
|
||||
Sample Input
|
||||
1
|
||||
2
|
||||
Sample Output
|
||||
0
|
||||
1
|
||||
'''
|
||||
a=[0,0,1]
|
||||
for i in range(3,1010):
|
||||
a.append((i-1)*(a[i-2]+a[i-1]))
|
||||
while True:
|
||||
try:
|
||||
n=int(input())
|
||||
print(a[n])
|
||||
except:
|
||||
break
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
B. 篮球宝贝
|
||||
Description
|
||||
篮球宝贝既是激烈的篮球比赛之中,给赛场的紧张气氛带来些许放松的篮球拉拉队,同时为球迷和球员加油鼓劲的拉拉队员,而且篮球拉拉队的表演也非常精彩。篮球宝贝就是被球迷爱称为“篮球宝贝”的拉拉队员。今年NIT篮球协会要在学校内选一批篮球宝贝,学校很支持这项活动,把愿意参加活动的学生名单全部提供出来了,现在需要聪明的你来帮助活动的主办方完成这项任务。学校提供的名单信息含有性别、身高、年级三项内容,而篮球宝贝只能是大一或者大二的符合身高要求的女生,现在请你编程实现。
|
||||
|
||||
Input
|
||||
本问题有多组测试数据,而且输入的第一行就是测试数据的组数。对于每一组测试数据,共有三部分;第一部分只有一行是两个整数n和m,n表示学生总数,m表示需要选拔的篮球宝贝的人数,其中1<=n<=20000,1<=m<=50,两数之间有空格分隔;第二部分也是一行是篮球宝贝所要求的身高,用两个整数F和T表示,也就是说F<=选中的学生的身高<=T,其中150<=F<=T<=180,两数之间有空格分隔;最后一部分有n行是学生的数据,每行有三个整数组成,第一个整数S表示性别,其中S=0表示女生,S=1表示男生,第二个整数H表示身高,第三个整数G表示年级,其中1<=G<=4,三个整数之间分别有空格隔开。
|
||||
|
||||
Output
|
||||
对于每一组测试数据,输出只有一行,就是第m个满足要求的学生的输入顺序号(即在输入数据中是第几个学生)。如果没有符合结果的,那么输出”No such student!”。
|
||||
|
||||
Sample Input
|
||||
2
|
||||
3 1
|
||||
160 165
|
||||
1 181 2
|
||||
0 162 3
|
||||
0 163 2
|
||||
3 2
|
||||
160 165
|
||||
1 180 1
|
||||
0 165 1
|
||||
0 163 3
|
||||
Sample Output
|
||||
3
|
||||
No such student!
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long ll;
|
||||
|
||||
int main()
|
||||
{
|
||||
int t;
|
||||
scanf("%d",&t);
|
||||
int a,b,c;
|
||||
while(t--)
|
||||
{
|
||||
int n,m,l,r;
|
||||
cin>>n>>m>>l>>r;
|
||||
int ans=0;
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
cin>>a>>b>>c;
|
||||
if(m==0)continue;
|
||||
if(a==0&&b<=r&&b>=l&&c<=2)
|
||||
{
|
||||
m--;
|
||||
}
|
||||
if(!m)
|
||||
{
|
||||
ans=i+1;
|
||||
}
|
||||
}
|
||||
if(!m)cout<<ans<<endl;
|
||||
else cout<<"No such student!"<<endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#
|
||||
'''
|
||||
D. 自增自减运算
|
||||
Description
|
||||
小胖子正在学习汇编语言,汇编语言里面有自增和自减指令,叫inc和dec指令,其实C语言里面也有自增和自减运算的,即++和—运算,但这些指令或者运算都是有范围的,现在小胖子碰到了很长很长的整数,小胖子脑子一转,很快就想出来。现在请你也实现这个自增和自减运算。
|
||||
|
||||
Input
|
||||
输入有多组,第一行是测试数据的组数。对于每一组测试数据,共有两行,其中第一行是一个整数M(0表示自减运算,1表示自增运算);第二行是一个很长的整数,它的位数不超过10000位,输入一定符合数学规定的要求并且不会有多余的字符。
|
||||
|
||||
Output
|
||||
输出只有一行。
|
||||
|
||||
Sample Input
|
||||
2
|
||||
0
|
||||
100
|
||||
1
|
||||
200
|
||||
Sample Output
|
||||
99
|
||||
201
|
||||
'''
|
||||
t=int(input())
|
||||
for i in range(t):
|
||||
m=int(input())
|
||||
a=int(input())
|
||||
if m==0:
|
||||
a-=1
|
||||
else:
|
||||
a+=1
|
||||
print(a)
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
A. 英语成绩分析
|
||||
Description
|
||||
NIT学校前不久刚结束了一次大一学生的英语测试,分管教学的副校长想知道全校最高分与排名第二十名学生的分差是多少,还想知道最高分与平均分的分差是多少,请你帮忙算一下。
|
||||
|
||||
Input
|
||||
本问题有多组测试数据,第一行输入的就是测试数据组数,对于每组数据,有两行。其中第一行就是学生的个数n(21<=n<=2000);第二行是n个整数,表示n个学生的英语成绩(0<=每个学生的英语成绩<=100)。
|
||||
|
||||
Output
|
||||
对于每组测试数据,输出也有两行,第一行是最高成绩与排名第二十名学生的成绩分差,第二行是最高分与平均分的分差(精确到小数点后2位)。
|
||||
|
||||
Sample Input
|
||||
2
|
||||
30
|
||||
65 71 94 83 62 77 81 96 80 70 66 72 95 84 63 78 82 97 81 71 64 70 93 82 61 76 80 95 79 69
|
||||
22
|
||||
77 81 96 80 70 66 72 95 84 63 78 82 97 81 71 64 70 93 82 61 76 80
|
||||
Sample Output
|
||||
26
|
||||
19.10
|
||||
33
|
||||
18.86
|
||||
*/
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long ll;
|
||||
double a[2010];
|
||||
|
||||
int main()
|
||||
{
|
||||
int n,t;
|
||||
scanf("%d",&t);
|
||||
while(t--)
|
||||
{
|
||||
scanf("%d",&n);
|
||||
double sum=0;
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
scanf("%lf",&a[i]);
|
||||
sum+=a[i];
|
||||
}
|
||||
sort(a,a+n);
|
||||
reverse(a,a+n);
|
||||
printf("%.0f\n",a[0]-a[19]);
|
||||
printf("%.2f\n",a[0]-sum/n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue