模拟+贪心

零件加工任务的安排一
Description
有个国有中型企业,接到一批需要加工零件的订单,员工们非常高兴,可是高兴之后却发现问题了,原来这家企业能够加工这批零件的机床有限,如果仅仅为了这批加工任务而新添机床的话,那么既不合算也不必要,因为加工完这批零件后很可能这些机床又要闲置起来,所以大批量购买肯定不行,但这批订单又必须要完成,那么这么办呢?很想请你帮忙设计一个安排加工任务,使得完成这批订单所需要使用的机器数量最少。

假定对于待加工的第i个零件,给你两个非负整数Si,Ei,其中Si表示加工开始的时间,其中Ei表示加工结束的时间,由于受到客观条件的制约,这开始和结束的时间限制必须要遵守。当然在某个时刻一台机器只能加工一个零件。

Input
本问题有多组测试数据,对于每组测试数据,输入的第一行是需要加工的零件个数N(0<=N<=1000),接着是N行[Si,Ei],,其中Si,Ei如上所述(0<=Si<=Ei<=10000),

Output
输出只有一行,就是完成加工任务所需要的最少机床数。

Sample Input
7
[1,3]
[1,4]
[2,5]
[3,7]
[4,7]
[6,9]
[7,8]
Sample Output
3

#include<bits/stdc++.h>
using namespace std;
struct lj{
	int si;
	int ei;	
};
int n;
lj a[1001],b[1001];
bool bj(const lj &u,const lj &v);
int main()
{
	int nsj,xzt,ljmng;
	while(cin>>n)
	{
		for(nsj=1;nsj<=n;nsj++)
		{
			scanf(" [%d,%d]",&a[nsj].si,&a[nsj].ei);
		}
		memset(b,0,sizeof(b));
		sort(a+1,a+n+1,bj);
		xzt=0;
		for(nsj=1;nsj<=n;nsj++)
		{
			for(ljmng=1;ljmng<=xzt;ljmng++)
			{
				if(b[ljmng].ei<=a[nsj].si)
				{
					break;
				}
			}
			if(ljmng<=xzt)
			{
				b[ljmng].ei=a[nsj].ei; 
			}
			else
			{
				xzt++;
				b[xzt].si=a[nsj].si;
				b[xzt].ei=a[nsj].ei;
			}
		}
		cout<<xzt<<endl;
	}
	return 0;
}
bool bj(const lj &u,const lj &v)
{
	if(u.si==v.si)
	{
		return u.ei<v.ei; 
	}
	return u.si<v.si;
}

零件加工问题二
Description
有个国有中型企业,接到一批需要加工零件的订单,员工们非常高兴,工厂领导为了鼓励员工尽快地完成加工任务,出台了奖励政策:“如果在保证质量要求的前提下,每完成一个零件加工任务,都有相同数量的奖金!”。所以所有员工都希望加工尽量多的零件,以便拿到更多的奖金。现在请你帮忙,怎样加工才能在一台机床上加工最多的零件。

假定对于待加工的第i个零件,给你两个非负整数Si,Ei,其中Si表示加工开始的时间,其中Ei表示加工结束的时间,由于受到客观条件的制约,这开始和结束的时间限制必须要遵守。当然在某个时刻一台机器只能加工一个零件。

Input
本问题有多组测试数据,对于每组测试数据,输入的第一行是三个非负的整数N(0<=N<=1000),TB,TE(0<=TB<=TE<=10000),其中N表示需要加工的零件个数,TB和TE分别表示给定的时间范围,即要求在TB和TE的时间内加工尽量多的零件。接着是N行[Si,Ei],其中Si,Ei如上所述(0<=Si<=Ei<=10000),而且规定零件编号顺序就是输入的顺序。

Output
输出只有一行就是能够加工的最多的零件数;

Sample Input
7 0 10
[4,7]
[2,5]
[1,3]
[7,8]
[3,7]
[1,4]
[6,9]
Sample Output
3

#include<bits/stdc++.h>
using namespace std;
struct lj{
	int si;
	int ei;	
};
int n;
lj a[1001],b[1001];
bool bj(const lj &u,const lj &v);
int main()
{
	int nsj,xzt,ljmng,tb,te,x,y,ztgs,dztgs;
	while(cin>>n>>tb>>te)
	{
		ztgs=0;
		for(nsj=1;nsj<=n;nsj++)
		{
			scanf(" [%d,%d]",&x,&y);
			if(tb<=x&&y<=te)
			{
				ztgs++;
				a[ztgs].si=x;
                a[ztgs].ei=y;
			}
		}
		memset(b,0,sizeof(b));
		sort(a+1,a+ztgs+1,bj);
		xzt=0;
		dztgs=0;
		for(nsj=1;nsj<=ztgs;nsj++)
		{
			for(ljmng=1;ljmng<=dztgs;ljmng++)
			{
				if(b[ljmng].ei<=a[nsj].si)
				{
					break;
				}
			}
			if(ljmng<=dztgs)
			{
				b[ljmng].ei=a[nsj].ei; 
				if(ljmng==1)
                {
                    xzt++;
                }
			}
			else
			{
				dztgs++;
                b[dztgs].ei=a[nsj].ei;
                b[dztgs].si=a[nsj].si;
                if(ljmng==1)
                {
                    xzt++;
                }
			}
		}
		cout<<xzt<<endl;
	}
	return 0;
}
bool bj(const lj &u,const lj &v)
{
	if(u.ei==v.ei)
	{
		return u.si<v.si; 
	}
	return u.ei<v.ei;
}

看亚运
Description
亚运会已经开始好几天了,估计很多热爱运动的ACMer也会抛开电脑,奔向电视了。亚运会不是每年都有的,所以一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、我爱记歌词,以及非诚勿扰等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)。

Input
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。

Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。

Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5

#include<bits/stdc++.h>
using namespace std;
struct lj{
	int si;
	int ei;	
};
int n;
lj a[1001],b[1001];
bool bj(const lj &u,const lj &v);
int main()
{
	int nsj,xzt,ljmng,x,y,ztgs,dztgs;
	while(cin>>n)
	{
		if(n==0)
		{
			break;
		}
		for(nsj=1;nsj<=n;nsj++)
		{
			scanf("%d%d",&x,&y);
			a[nsj].si=x;
            a[nsj].ei=y;
		}
		memset(b,0,sizeof(b));
		sort(a+1,a+n+1,bj);
		xzt=0;
		dztgs=0;
		for(nsj=1;nsj<=n;nsj++)
		{
			for(ljmng=1;ljmng<=dztgs;ljmng++)
			{
				if(b[ljmng].ei<=a[nsj].si)
				{
					break;
				}
			}
			if(ljmng<=dztgs)
			{
				b[ljmng].ei=a[nsj].ei; 
				if(ljmng==1)
                {
                    xzt++;
                }
			}
			else
			{
				dztgs++;
                b[dztgs].ei=a[nsj].ei;
                b[dztgs].si=a[nsj].si;
                if(ljmng==1)
                {
                    xzt++;
                }
			}
		}
		cout<<xzt<<endl;
	}
	return 0;
}
bool bj(const lj &u,const lj &v)
{
	if(u.ei==v.ei)
	{
		return u.si<v.si; 
	}
	return u.ei<v.ei;
}

基站安装
Description
从前有一个一望无际的海滩,海滩后面是陆地,前面是广阔的大海。海中有很多小岛(可以用一个点表示)。现在海滩上需要安装一些基站(海滩上的任意位置)这样岛上的居民就能用手机通话了,所有的基站的覆盖距离都是d,在距离d范围内的小岛都能收到基站发送的信号。

我们用笛卡尔坐标系来表示这个问题,定义x轴为海滩,x轴上方是大海,下方是陆地。现给出每个小岛的位置(用x-y坐标表示)和基站的覆盖范围d,你的任务就是写一个程序,计算出可以覆盖所有的小岛,至少需要在海滩上安装多少基站?

Input
输入包含多组数据。对每组数据,第一行包含两个整数n(1 <= n <= 1000)和d,n代表小岛数量,d代表基站的覆盖距离。接下来有n行,每行包含两个整数,表示小岛的位置坐标。输入n=0,d=0时退出。

Output
对每组数据,输出包含数据组数,格式如sample,后跟最少需要安装的基站数,如果无解,输出-1。

Sample Input
3 2
1 2
-3 1
2 1
1 2
0 2
1 -2
0 2
0 0
Sample Output
Case 1: 2
Case 2: 1
Case 3: -1

#include<bits/stdc++.h>
using namespace std;
struct dao
{
	int x,y;
};
struct xian
{
	double qs,zz;
};
dao a[1001];
xian b[1001];
bool bj(const xian &u,const xian &v);
bool pd(int n,int d);
int main()
{
	int n,d,zs,i,ans;
	double t250;
	zs=0;
	while(cin>>n>>d)
	{
		if(n==0&&d==0)
		{
			break;
		}
		for(i=1;i<=n;i++)
		{
			scanf("%d%d",&a[i].x,&a[i].y);
		}
		if(pd(n,d))
		{
			sort(b+1,b+n+1,bj);
			ans=1;
			t250=b[1].zz;
			for(i=2;i<=n;i++)
			{
				if(b[i].qs>t250)
				{
					ans++;
					t250=b[i].zz;
				}
				else
				{
					if(b[i].zz<t250)
					{
						t250=b[i].zz;
					}
				}
			}
		}
		else
		{
			ans=-1;
		}
		zs++;
		printf("Case %d: %d\n",zs,ans);
	}
	return 0;
}
bool bj(const xian &u,const xian &v)
{
    return u.qs<v.qs;
}
bool pd(int n,int d)
{
	int i;
    double t;
    for(i=1;i<=n;i++)
    {
        if(a[i].y>d)
        {
        	return false;
		}
        t=sqrt(d*d-a[i].y*a[i].y);
        b[i].qs=a[i].x-t;
        b[i].zz=a[i].x+t;
    }
    return true;
}

打包问题
Description
一个工厂把产品包装在正方形的箱子里,尺寸有1×1,2×2,3×3,4×4,5×5,6×6六种,高度为h。产品最终总是捆扎成高度为h的6×6的包裹箱子送到客户手里,因为客户希望包裹箱子越少越好。请你编写一个程序计算最少需要多少只包裹箱子才能把客户买的产品送完。

Input
输入包含多组数据。每组数据有一行,包含6个整数,用空格隔开,分别代表1×1的产品、2×2的产品……6×6的产品的个数。输入6个0时退出。

Output
每组数据输出一行,输出最少需要的包裹箱子数。

Sample Input
0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0
Sample Output
2
1

#include<bits/stdc++.h>
int h;
using namespace std;
int main()
{
	int a[7],i,s,ys,n6x6,n5x5,n4x4,n3x3,n2x2,n1x1;
	while(1)
	{
		n3x3 = n2x2 = n1x1 = s = n6x6 = n5x5 = n4x4 = 0;
		for(i=1;i<=6;i++)
		{
			scanf("%d",&a[i]);
			s+=a[i];
		}
		if(s==0)
		{
			return 0;
		}
		n6x6 += a[6]+a[5]+a[4];
		n2x2 +=5*a[4];
		ys = a[3]%4;
		n6x6 += a[3]/4;
		if(ys!=0)
		{
			n6x6++;
			if(ys==3)
			{
				n2x2++;
			}
			else
			{
				if(ys==2)
				{
					n2x2+=3;
				}
				else
				{
					n2x2 += 5;
				}
			}
		}
		if(a[2]>n2x2)
		{
			ys=(a[2]-n2x2)%9;
			n6x6+=(a[2]-n2x2)/9;
			if(ys!=0)
			{
				n6x6++;
			}
		}
		n1x1=n6x6*36-a[6]*36-a[5]*25-a[4]*16-a[3]*9-a[2]*4;
		if(a[1]>n1x1)
		{
			n6x6+=(a[1]-n1x1)/36;
			ys=(a[1]-n1x1)%36;
			if(ys!=0)
			{
				n6x6++;
			}
		}
		printf("%d\n",n6x6);
	}
}

上课问题
Description
题目大意:北大的很多研究生住在万柳校区,他们每天要坐公交或骑车去4.5公里远的燕园上课。由于北京的交通很烂(我想也是很烂),许多同学选择骑车去上课。查理同学和其他同学的骑车习惯不同,其他同学都是以固定的速度骑行,查理则是跟某个MM一起,这样就不会觉得无聊。当查理出发的时候,他会寻找一个MM作伴去燕园。如果找到了PLMM,他就会和她一起,否则就继续物色。在去燕园的路上,如果有某个MM速度比较快,超过他了,他就会丢下身边的MM去追那个更快的MM,然后和她一起去燕园。我们假设查理出发的时刻为0,现给出很多MM的出发时间和速度,你来计算一下查理什么时候能到燕园呢?

Input
包含多组数据。每组数据第一行以个整数N(1<=N<=10000),代表MM数,N=0时退出,接下来有N行,每行代表一个MM的骑行信息。格式:Vi ,Ti。0 < Vi <= 40,代表骑车速度(km/h),Ti是该MM的出发时间(s),Ti可能小于0。

Output
每行输出代表一组数据。输出查理到达燕园的时间,不满1秒的按1秒算。

Sample Input
4
20 0
25 -155
27 190
30 240
2
21 0
22 34
0
Sample Output
780
771

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i,n;
    double mm,ti,vi,mi,tt;
    while(cin>>n)
    {
    	if(n==0)
    	{
    		break;
		}
        mm=999999999.0;
        for(i=1;i<=n;i++)
        {
            cin>>vi>>ti;
            tt=4.5*3600/vi+ti;
            if(ti>=0.0)
	        {
	            if(mm>tt)
	            {
	                mm=tt;
	            }
	        }
        }
        mi=ceil(mm);
        cout<<mi<<endl;
    }
    return 0;
}

今年暑假不AC
Description
“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%…”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
Input
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5

#include<bits/stdc++.h>
using namespace std;
struct lj{
	int si;
	int ei;	
};
int n;
lj a[1001],b[1001];
bool bj(const lj &u,const lj &v);
int main()
{
	int nsj,xzt,ljmng,x,y,ztgs,dztgs;
	while(cin>>n)
	{
		if(n==0)
		{
			break;
		}
		for(nsj=1;nsj<=n;nsj++)
		{
			scanf("%d%d",&x,&y);
			a[nsj].si=x;
            a[nsj].ei=y;
		}
		memset(b,0,sizeof(b));
		sort(a+1,a+n+1,bj);
		xzt=0;
		dztgs=0;
		for(nsj=1;nsj<=n;nsj++)
		{
			for(ljmng=1;ljmng<=dztgs;ljmng++)
			{
				if(b[ljmng].ei<=a[nsj].si)
				{
					break;
				}
			}
			if(ljmng<=dztgs)
			{
				b[ljmng].ei=a[nsj].ei; 
				if(ljmng==1)
                {
                    xzt++;
                }
			}
			else
			{
				dztgs++;
                b[dztgs].ei=a[nsj].ei;
                b[dztgs].si=a[nsj].si;
                if(ljmng==1)
                {
                    xzt++;
                }
			}
		}
		cout<<xzt<<endl;
	}
	return 0;
}
bool bj(const lj &u,const lj &v)
{
	if(u.ei==v.ei)
	{
		return u.si<v.si; 
	}
	return u.ei<v.ei;
}

食堂排队买菜问题
Description
宁波理工学院有好几个食堂,每当中午下课吃饭时,人会很多,每个同学的口味也可能不同,现有n同学要买自己喜欢吃的饭菜,已知每个同学买饭菜所需要的时间为ti,(0<i<=n),请求出一种排队次序,使每个同学买好饭菜的时间总和为最小。

Input
输入有多组测试数据,对于每一组测试数据,输入的第1行一个正整数n(n<=10000),第2行有n 个不超过 100的正整数ti,单位为秒. 数与数之间有空格。

Output
对于每一组测试数据,输出n个同学买好饭菜所需时间的总和的最小值。

Sample Input
4
5 9 6 7
Sample Output
61

#include<bits/stdc++.h>
using namespace std;
int a[10001];
int main()
{
    int n,i,s,k;
    while(cin>>n)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d",a+i);
        }
        sort(a+1,a+n+1);
        k=n;
        s=0;
        for(i=1;i<=n;i++)
        {
            s+=k*a[i];
            k--;
        }
        cout<<s<<endl;
    }
    return 0;
}

高速公路维修问题
Description
最近十几年,我们国家的高速公路发展迅速,覆盖全国的高速公路里程数逐年增加,由于建设速度快,也带来了一个问题,那就是高速公路的建设质量令人担心,但并不是所有的问题都是由建设质量一方面造成的,长期的超载超限运营也会造成路基路面的损坏,我们常常看到有些路段的路面坑坑洼洼的,一旦路面出现问题,很有可能造成严重的交通事故,因此需要修复,高速公路的修复有很多特殊性,比如一个小的坑洼,不是补一补就可以的,需要在坑洼的附近一段里面都挖掉重新铺设材料,哪怕是只有一个小的坑洼也一样,甚至一个小洼地的修补和很多个连在一起的洼地修复的成本是一样的。现在我们把一个最小的修复长度算作一个修补单位,在这个长度范围内一个洼地和多个洼地的修补成本是一样的,现在给你在一条高速公路上所有的洼地的位置(我们假定起点为高速公路的一端,另一端足够长),请你帮忙写个程序计算一下,如要修复所有的洼地,最少需要多少个修补单位。

Input
本问题有多组测试数据,每一组数据有两行,第一行有两个整数N和L(中间用空格分隔),分别表示N(0<=N<=1000)个洼地和修补单位的长度L(0<L<=100)。第二行共有N个整数a1,a2…an(用空格分隔),分别表示N个洼地的位置(0<=ai<=20000)。

Output
对于每组输入只有一行输出,即最少需要的修补单位个数。

Sample Input
2 50
10 61
4 50
10 59 60 61
Sample Output
2
2

#include<bits/stdc++.h>
using namespace std;
int n,l,a[1001],k,b,i;
int main()
{
	while(cin>>n>>l)
    {
        for(i=1;i<=n;i++)
            scanf("%d",a+i);
		sort(a+1,a+n+1);
        k=1;
        b=a[1];
        for(i=2;i<=n;i++)
        {
            if(a[i]-b>l)
            {
                k++;
                b=a[i];
            }
        }
        if(n==0)
            k=0;
        cout<<k<<endl;
    }
	return 0;
}

独木桥
Description
战争已经进入到紧要时间。你是运输小队长,正在率领运输部队向前线运送物资。运输任务像做题一样的无聊。你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在桥下欣赏士兵们。士兵们十分愤怒,因为这座独木桥十分狭窄,只能容纳1个人通过。假如有2个人相向而行在桥上相遇,那么他们2个人将无法绕过对方,只能有1个人回头下桥,让另一个人先通过。但是,可以有多个人同时呆在同一个位置。

突然,你收到从指挥部发来的信息,敌军的轰炸机正朝着你所在的独木桥飞来!为了安全,你的部队必须撤下独木桥。独木桥的长度为L,士兵们只能呆在坐标为整数的地方。所有士兵的速度都为1,但一个士兵某一时刻来到了坐标为0或L+1的位置,他就离开了独木桥。

每个士兵都有一个初始面对的方向,他们会以匀速朝着这个方向行走,中途不会自己改变方向。但是,如果两个士兵面对面相遇,他们无法彼此通过对方,于是就分别转身,继续行走。转身不需要任何的时间。

由于先前的愤怒,你已不能控制你的士兵。甚至,你连每个士兵初始面对的方向都不知道。因此,你想要知道你的部队最少需要多少时间就可能全部撤离独木桥。另外,总部也在安排阻拦敌人的进攻,因此你还需要知道你的部队最多需要多少时间才能全部撤离独木桥。

Input
第一行:一个整数L,表示独木桥的长度。桥上的坐标为1…L

第二行:一个整数N,表示初始时留在桥上的士兵数目

第三行:有N个整数,分别表示每个士兵的初始坐标。

Output
只有一行,输出2个整数,分别表示部队撤离独木桥的最小时间和最大时间。2个整数由一个空格符分开。

Sample Input
4
2
1 3
Sample Output
2 4
Hint
初始时,没有两个士兵同在一个坐标。

数据范围N≤L≤5000。

#include<bits/stdc++.h>
using namespace std;
int a[5001];
int main()
{
	int l,n,i,dd,xx,mx,mi;
	cin>>l>>n;
	mx=0;
	mi=0;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		dd=max(l-a[i]+1,a[i]);
		xx=min(l-a[i]+1,a[i]);
		mx=max(mx,dd);
		mi=max(mi,xx);
	}
	cout<<mi<<' '<<mx<<endl;
	return 0;
}

纪念品分组
Description
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

Input
共n+2行:

第1行包括一个整数w,为每组纪念品价格之和的上上限。

第2行为一个整数n,表示购来的纪念品的总件数G。

第3至n+2行每行包含一个正整数Pi​(5≤Pi​≤w)表示所对应纪念品的价格。

Output
一个整数,即最少的分组数目。

Sample Input
100
9
90
20
20
30
50
60
70
80
90
Sample Output
6
Hint
50%的数据满足: 1≤n≤15

100%的数据满足:1≤n≤30000,80≤w≤200

#include<bits/stdc++.h>
using namespace std;
long long n,x,num=0; 
int a[5000000];
int main()
{
	cin>>x>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];	
	} 
	sort(a,a+n);
	int i=0,j=n-1;
	while(i<=j)
	{
		if(a[i]+a[j]>x)
		{
			num++;
			j--;
		}
		else if(a[i]+a[j]<=x)
		{
			num++;
			i++;
			j--;
		}
	}
	cout<<num<<endl;
	return 0;
}

守望者的逃离
Description
恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。守望者的跑步速度为17m/s,以这样的速度是无法逃离荒岛的。庆幸的是守望者拥有闪烁法术,可在1s内移动60m,不过每次使用闪烁法术都会消耗魔法值10点。守望者的魔法值恢复的速度为4点/s,只有处在原地休息状态时才能恢复。

现在已知守望者的魔法初值M,他所在的初始位置与岛的出口之间的距离S,岛沉没的时间T。你的任务是写一个程序帮助守望者计算如何在最短的时间内逃离荒岛,若不能逃出,则输出守望者在剩下的时间内能走的最远距离。注意:守望者跑步、闪烁或休息活动均以秒(s)为单位,且每次活动的持续时间为整数秒。距离的单位为米(m)。

Input
共一行,包括空格隔开的三个非负整数M, S, T。

Output
共两行。

第1行为字符串“Yes”或“No”(区分大小写),即守望者是否能逃离荒岛。

第2行包含一个整数。第一行为“Yes”(区分大小写)时表示守望者逃离荒岛的最短时间;第一行为“No”(区分大小写)时表示守望者能走的最远距离。

Sample Input
【输入样例1】
39 200 4
【输入样例2】
36 255 10
Sample Output
【输出样例1】
No
197
【输出样例2】
Yes
6
Hint
30%的数据满足: 1≤T≤10,1≤S≤100

50%的数据满足: 1≤T ≤1000,1≤S≤10000

100%的数据满足:1≤T≤300000,0≤M≤1000,1≤S≤10^8.

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int m,s,t,tlm,tlm1,t1,i;
	cin>>m>>s>>t;
	t1=tlm1=tlm=0;
	for(i=1;i<=t;i++)
	{
		tlm+=17;
		if(m>=10)
		{
			m-=10;
			tlm1+=60;
		}
		else
		{
			m+=4;
		}
		tlm=max(tlm,tlm1);
		if(tlm>s)
		{
			cout<<"Yes"<<endl<<i<<endl;
			return 0;
		}
	}
	cout<<"No"<<endl<<tlm<<endl;
    return 0;
} 

学生分组
Description
有N组学生,给出初始时每组中的学生个数,再给出每组学生人数的上界R和下界L(L≤R),每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使N组学生的人数都在[L,R]中。

Input
第一行一个整数N,表示学生组数; n≤50

第二行N个整数,表示每组的学生个数;

第三行两个整数L,R,表示下界和上界。

Output
一个数,表示最少的交换次数,如果不能满足题目条件输出−1

Sample Input
2
10 20
10 15
Sample Output
5

#include<bits/stdc++.h>
using namespace std;
int a[51];
int main()
{
	int n,l,r,i,s,t1,t2,mx;
	cin>>n;
	s=0;
	t1=0;
	t2=0;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
		s+=a[i];
	}
	cin>>l>>r;
	for(i=1;i<=n;i++)
	{
		if(a[i]>r)
		{
			t1+=a[i]-r;
		}
		if(a[i]<l)
		{
			t2+=l-a[i];
		}
		
	}
	mx=n*r;
	if(mx<s)
	{
		cout<<-1<<endl;
		return 0;
	}
	cout<<max(t1,t2)<<endl; 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值