欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Week3 作业

程序员文章站 2022-07-09 18:53:07
...

Week3 作业

A题:选数问题(DFS)
问题描述:
给定n个数,从里面挑选K个数,使得它们的总和为S。输入共有T组数据(T<=100),每组数据有两行,第一行为n,K,S,第二行为n个数。输出共几种总和为S的数的组合。

解题思路:
举例说明:
有三个位置等待放数 ,共有1,2,3,4,5,6,7,8,9,10,十个数字,例如在某次DFS中,2放在第一个位置,则第二个位置只能从3-10选择一个,又如第二个位置选择了5,则第三个位置只能从6-10选择一个。即为,当前位置选数,从前一个位置选择数字的下一个数字开始,不能回头。代码中的last记录这个数字位置。

代码实现:

#include<iostream>
using namespace std;
int n,k,s,ans;
int a[100];


void dfs(int t,int sum,int last)
{
	if(t==k)
	{
		if(sum==s) ans++;
	}
	else 
	{
		for(int i=last;i<n;i++)
			dfs(t+1,sum+a[i],i+1);
	}
}

int main()
{
	int nn;
	cin>>nn;
	while(nn--)
	{
		cin>>n>>k>>s;
		for(int i=0;i<n;i++)
			cin>>a[i];
		ans=0;
		dfs(0,0,0);
		cout<<ans<<endl;
		
	}
}

B题:区间选点(贪心)

问题描述:
数轴上有n个闭区间[a_i,b_i]。取尽量少的点,使得每个区间内都至少有一个点。输入N个整数(N<=100),之后N行每行两个整数a,b (a,b<=100)。输出选择点的个数。

解题思路:
1.设置区间的结构体数据结构,左端点和右端点,左端点升序,右端点降序。
2.now记录在现有的点的情况下,区间伸展的最右距离,起初点的个数为0,now为-1 。
3. 循环执行以下过程,将now与下一个区间的左端点比较,若now大,now赋值迁移到下一个区间的右端点,若now小,选点个数加一,now赋值迁移到下一个区间的右端点,直到遍历完所有区间结束。

代码实现:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct qj
{
	int l;
	int r;
	qj(int _l,int _r)
	{
		l=_l;
		r=_r;
	}
	bool  operator< (const qj& q)
	{
		if(r!=q.r) return r <q.r;
		else return l>q.l;
	}
};
int main()
{
	int n;
	cin>>n;
	vector<qj> v;
	while(n--)
	{
		int a,b;
		cin>>a>>b;
		qj x = qj(a,b);
		v.push_back(x);
	}
	sort(v.begin(),v.end());
	int count = 0;
	int now = -1;
	for(int i=0;i<v.size();i++)
	{
		if(v[i].l>now)
		{
			now = v[i].r;
			count++;
		}
	}
	cout<<count<<endl;
}

C题:区间覆盖(贪心)
问题描述:
数轴上有n(1<=n<=25000)个闭区间[ai,bi],选择尽量少的区间覆盖一条指定线段[1,T] (1<=T<=1000000)。覆盖整点,即[1,2]+[3,4]可以覆盖[1,4]。不可能办到输出-1。输入第一行为n和T,之后N行每行一个闭区间。输出选择区间的数目,不可能办到输出-1。

解题思路:
1.设置区间的结构体数据结构,左端点,右端点,左端点升序排列,有了这样的升序序列,我们只需要遍历一次所有区间即可。
2.两个重要变量,maxlen和nowbegin。nowbegin是当前覆盖到的最远距离,选择一个下面的区间,该区间满足这样的条件:左端点小于nowbegin,且右端点最大。用maxlen记录这个最大距离,然后用maxlen更新nowbegin。
3.循环的停止条件:a.下一个区间左端点没有小于nowbegin的,表示覆盖失败。b.所有区间已被遍历完成,此时需要判断nowbegin是否已经大于目标区间右端点。

代码实现:

#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
struct qj
{
	int l;
	int r;
	bool operator <(const qj& p)
	{
		 return l<=p.l;
		
	}
	qj(int x,int y):l(x),r(y){};
	qj(){};
};


int main()
{
	int begin =1,end,n,count = 0;
	cin>>n>>end;
	qj *v = new qj [n];
	int nowbegin = begin;
	for(int i=0;i<n;i++)
	{	
		scanf("%d%d",&v[i].l,&v[i].r);
	}
	sort(v,v+n);
	int i=0;
	int maxlen = 1;
	while(nowbegin<=end)
	{	
		if(v[i].l>nowbegin) break;
		bool flag = false;
		for(;v[i].l<=nowbegin&&i<n;i++)
		{
			if(v[i].r>maxlen)
			{
				maxlen = v[i].r;
				flag = true;
			}
				
			
		}
		if(flag)
		{
			nowbegin = maxlen + 1;
			count ++;
		}
		if(i==n) break;
	
		
	}
	if(nowbegin>end) cout<<count<<endl;
	else cout<<-1<<endl;
	
	
}


上一篇: Week3 作业

下一篇: Base64加密、解密