2021-02-08

B - 补提交卡

蒜头君给自己定了一个宏伟的目标:连续
100
天每天坚持在计蒜客题库提交一个程序。
100
天过去了,蒜头君查看自己的提交记录发现有
N
天因为贪玩忘记提交了。于是蒜头君软磨硬泡、强忍着花椰菜鄙视的眼神从花椰菜那里要来
M
张 “补提交卡”。每张 “补提交卡” 都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。蒜头君想知道通过利用这
M
张补提交卡,可以使自己的 “最长连续提交天数” 最多变成多少天。

输入格式
在这里插入图片描述

输出格式
对于每组数据,输出通过使用补提交卡蒜头君的最长连续提交天数最多变成多少。

Sample Input
3
5 1
34 77 82 83 84
5 2
10 30 55 56 90
5 10
10 30 55 56 90
Sample Output
76
59
100

思路 就是找差n 数据间的差值
关键在于考虑第一个数据和最后一个数据 所以加a[0]=0;
a[n+1]=101;很关键

#include<stdio.h>
int a[1010];
int main()
{
	int n,m,x;
	int i,j;
	int cnt,max;
	scanf("%d",&x);
	while(x--)
	{
	
		scanf("%d %d",&n,&m);
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		if(m>=n)
		{
			printf("100\n");
			continue;
		}
		max=0;
		a[0]=0;
		a[n+1]=101;
		for(i=1;i<=n-m+1;i++) 
		{
			cnt=a[i+m]-a[i-1]-1;
			//printf("cnt=%d\n",cnt);
			if(cnt>max)
			max=cnt;
		}
		printf("%d\n",max);
	}
}

E - 数列极差

佳佳的老师在黑板上写了一个由 n 个正整数组成的数列,要求佳佳进行如下操作:每次擦去其中的两个数 a 和 b,然后在数列中加入一个数 a×b+1,如此下去直至黑板上剩下一个数为止,在所有按这种操作方式最后得到的数中,最大的为 max,最小的为 min, 则该数列的极差定义为 M=max−min。

由于佳佳忙于准备期末考试,现请你帮助他,对于给定的数列,计算出相应的极差 M。

输入格式
第一行为一个正整数 n 表示正整数序列的长度;
在接下来的 n 行中,每行输入一个正整数。
接下来的一行有一个 0,表示数据结束。

输出格式
输出只有一行,为相应的极差 d。

样例
Input Output
3
1
2
3
0
2
数据范围与提示
对于全部数据,0≤n≤50000,保证所有数据计算均在 32 位有符号整数范围内

贪心思想:每次选最小的运算 注意新算出来的数据需要与剩下的数据重新排序选择最小的

#include<stdio.h>
void quick_sort1(int left,int right,int a[])
{
	int i,j,temp,t;
	if(left>right)
	return;
	temp=a[left];
	i=left;
	j=right;
	while(i!=j)
	{
		while(a[j]>=temp&&i<j)
		j--;
		while(a[i]<=temp&&i<j)
		i++;
		//没相遇时交换
			if(i<j)
		{
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
		 
		
	}
	a[left]=a[i];
	a[i]=temp;
	quick_sort1(left,i-1,a);
	quick_sort1(i+1,right,a);
	return;	
 } 
 void quick_sort2(int left,int right,int a[])
{
	int i,j,temp,t;
	if(left>right)
	return;
	temp=a[left];
	i=left;
	j=right;
	while(i!=j)
	{
		while(a[j]<=temp&&i<j)
		j--;
		while(a[i]>=temp&&i<j)
		i++;
		//没相遇时交换
			if(i<j)
		{
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
		 
		
	}
	a[left]=a[i];
	a[i]=temp;
	quick_sort2(left,i-1,a);
	quick_sort2(i+1,right,a);
	return;	
 } 
int main()
{
	int a[1010],b[1010],n;
	int x,i,cnt=0,ans,sum1,sum2;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	//quick_sort(0,cnt-1);
	for(i=0;i<=n;i++)
	{
		b[i]=a[i];
	}
	quick_sort2(0,n-1,b);
	quick_sort1(0,n-1,a);
	/*for(i=0;i<n;i++)
	{
		printf("%d ",b[i]);
	}*/
	//for(i=0;i<cnt;i++)
	//printf("%d ",a[i]);
	for(i=0;i<=n-2;i++)
	{
		a[i+1]=a[i]*a[i+1]+1;
		b[i+1]=b[i]*b[i+1]+1;
		quick_sort1(i+1,n-1,a);
		quick_sort2(i+1,n-1,b);
	}
	//printf("%d %d",a[n-1],b[n-1]);
	printf("%d",a[n-1]-b[n-1]);
	
	
}

过河

UCAS_ACM小组的N名成员外出旅游,结果在路上碰到了一条河,岸边只有一艘船,这艘船最多只能载两人。
已知N名成员每人有一个过河时间ti,每次划船过河的时间等于船上成员的过河时间的最大值。请你找N名成员全部到底对岸的最少耗时。
输入
输入包含多组测试数据。第一行含有一个正整数T,表示数据组数。
每组数据的第一行含有一个整数N。接下来的一行含有N个整数,表示ti。
输出
对于每组输入数据输出一行,每行包括1个整数,代表该组数据下到对岸的最少耗时。
样例输入
2
4
1 2 5 10
5
1 2 8 7 6
样例输出
17
22
数据范围
1≤T≤20
1≤N≤1000
1≤ti≤100
提示
船划到对岸后不会自动飘回来的哦~

n>=4 时分两种情况 选择两种情况中时间较短的那个(每次会送去两个人 所以递推n-=2)
一种情况是 最快的和最慢去 最快的回来 最快的和次慢的去 最快的回来
另一种情况 最快的和次快的去 最快的回来 然后最慢的和次慢的去 次快的回来
n=3时 为三个时间的总和
n=2时 为较快的那个时间

#include<stdio.h> 
int a[1010];
void quick_sort(int left,int right)
{
	int i,j,temp,t;
	if(left>right)
	return;
	temp=a[left];
	i=left;
	j=right;
	while(i!=j)
	{
		while(a[j]>=temp&&i<j)
		j--;
		while(a[i]<=temp&&i<j)
		i++;
		//没相遇时交换
			if(i<j)
		{
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
		 
		
	}
	a[left]=a[i];
	a[i]=temp;
	quick_sort(left,i-1);
	quick_sort(i+1,right);
	return;	
 } 
int min(int x,int y)
{
	int m;
	m=x;
	if(y<x)
	m=y;
	return m;
}

int main()
{
	int x;
	int ans,i,j,s1,s2;
	scanf("%d",&x);
	while(x--)
	{	int n;
		ans=0,s1=0,s2=0;
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		//sort(a,a+n);
		quick_sort(1,n);
		while(n>0)
		{
			if(n>=4)
			{	s1=a[n]+a[n-1]+a[1]+a[1];
			    s2=a[1]+a[2]+a[n]+a[2];
				ans+=min(s1,s2);
				n=n-2;
			}
			else if(n==3)
			{	ans+=a[1]+a[2]+a[3];
				n=n-3;
			}
			else if(n<=2)
			{
				ans+=a[n];
				n=n-2;}
		}printf("%d\n",ans);


	}
}

H - 超市

超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润.
每天只能卖一个商品.
现在你要让超市获得最大的利润.
(原题说明过于抽象)

Input
多组数据.
每组数据第一行为N, 即超市的商品数目
之后N行数字. 第i行为 pi, di
N , pi, di <= 10000

Output
对于每一组数据, 输出当前条件下超市的最大利润

Sample Input
4
50 2
10 1
20 2
30 1

7
20 1
2 1
10 3
100 2
8 2
5 20
50 10
Sample Output
80
185

思路:以钱来排序 从一遍历对应时间 有空闲天数即可卖出
book用于标记是否卖出

#include<stdio.h>
#include<algorithm>
using namespace std;
int book[100001]; 
struct fact
{
	int money;
	int time;
}a[100001];
bool cmp(struct fact x,struct fact y)
{
	return x.money>y.money;
}
int main()
{
	int n,i,j,ans;
	while(scanf("%d",&n)!=EOF)
	{
		ans=0;
		for(i=0;i<n;i++)
		scanf("%d %d",&a[i].money,&a[i].time);
		sort(a,a+n,cmp);
		//for(i=0;i<n;i++)
		//printf("%d ",a[i].money);
		for(i=0;i<n;i++)
			for(j=a[i].time;j>=1;j--)
			{
				if(book[j]==0)
				{
					book[j]=1;
					ans+=a[i].money ;
					break;
				}
			}
			printf("%d\n",ans);
			for(i=0;i<=10000;i++)
				book[i]=0;
	}
	return 0;
}

O - 拯救X先生

话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了。显然,作为多年拼搏的商人,XHD不会坐以待毙的。
一天,当他正在苦思冥想解困良策的时候,突然想到了自己的传家宝,那是公司成立的时候,父亲作为贺礼送来的一个锦囊,徐父当时交代,不到万不得已的时候,不要打开它。“现在不正是最需要的时候吗?”,一边想,XHD一边找到了这个精心保管的锦囊,打开一看,里面只有一句话“杭城北麓千人洞有宝”。
二话不说,XHD拿起一个大口袋就出发了,这个千人洞他是知道的,小的时候,爸爸曾经带他来过这个隐蔽的路口,并告诉他,这是千人洞。他现在才明白爸爸当初这句话的含义。
尽管有点印象,XHD还是花了很大的精力才找到这个异常隐蔽的洞口,走进一看,几乎惊呆了,真的是眼花缭乱!不过尽管宝贝的种类不少,但是每种宝贝的量并不多,当然,每种宝贝单位体积的价格也不一样,为了挽救HDU,现在请你帮忙尽快计算出来XHD最多能带回多少价值的宝贝?(假设宝贝可以分割,分割后的价值和对应的体积成正比)
Input
输入包含多个测试实例,每个实例的第一行是两个整数v和n(v,n<100),分别表示口袋的容量和宝贝的种类,接着的n行每行包含2个整数pi和mi(0<pi,mi<10),分别表示某种宝贝的单价和对应的体积,v为0的时候结束输入。
Output
对于每个测试实例,请输出XHD最多能取回多少价值的宝贝,每个实例的输出占一行。
Sample Input
2 2
3 1
2 3
0

思路:体积相减作为判断条件

#include<stdio.h>
#include<algorithm> 
#include<cstdio>
using namespace std;
struct f
{
	int price;
	int v;
}a[1010];
bool cmp(f x, f y)
{
return x.price>y.price;
}

int main()
{
	int n,m,ans,sum=0,count=0,i;
	while(scanf("%d",&m)!=EOF)
	{	if(m==0)
		return 0;
		sum=0,count=0;
		scanf("%d",&n);
		for(i=0;i<n;i++)
		scanf("%d %d",&a[i].price,&a[i].v);
		ans=0;
		sort(a,a+n,cmp);
		for(i=0;i<n;i++)
		{
			if(m>=a[i].v)
			{
				ans+=a[i].price*a[i].v;
				m-=a[i].v;
				if(m==0)
				break;
			}
			else
			{
				ans+=(m*a[i].price);
				break;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

奇怪的电梯

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第ii层楼(1 \le i \le N)(1≤i≤N)上有一个数字K_i(0 \le K_i \le N)K ​ (0≤K i ≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3, 3 ,1 ,2 ,53,3,1,2,5代表了K_i(K_1=3,K_2=3,…)K
i (K1=3,K2 =3,…),从11楼开始。在11楼,按“上”可以到44楼,按“下”是不起作用的,因为没有-2−2楼。那么,从AA楼到BB楼至少要按几次按钮呢?
输入格式
共二行。
第一行为33个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1≤N≤200,1≤A,B≤N)。
第二行为NN个用空格隔开的非负整数,表示K_iK i。
输出格式
一行,即最少按键次数,若无法到达,则输出-1−1。
输入输出样例
输入 #1复制
5 1 5
3 3 1 2 5
输出 #1复制
3
典型搜素问题 学习点 一 cnt 二模板 dfs()函数中 结束条件 标记=1(开始遍历) 满足条件下一步没标记的话 进行下一步搜素 否则取消标记


#include<stdio.h>
int x,y,cnt,m=10000,i,book[1010],a[1010],n,ans;
void dfs(int c)
{
	if(cnt>=m)
	return;
	if(c==y)
	{
		m=cnt;
		return;
	}
	book[c]=1;
	cnt++;
	if(c+a[c]<=n&&book[c+a[c]]==0)
	dfs(c+a[c]);
	if(c-a[c]>=1&&book[c-a[c]]==0)
	dfs(c-a[c]);
	cnt--;
	book[c]=0;
} 
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
		return 0;
		scanf("%d %d",&x,&y);
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		dfs(x);
		if(m==10000)
		printf("-1\n");
		else
		printf("%d\n",m);}
}

(同样的题在洛谷能通过 vjudge平台上不行?)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值