1.29学习总结4

P1190 接水问题

题目描述

学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为 1。

现在有 n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1 到 n 编号,i 号同学的接水量为 wi​。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学 j 完成其接水量要求 wj​ 后,下一名排队等候接水的同学 k 马上接替 j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第 x 秒结束时完成接水,则 k 同学第 x+1 秒立刻开始接水。若当前接水人数 n′ 不足 m,则只有 n′ 个龙头供水,其它 m−n′ 个龙头关闭。

现在给出 n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。

输入格式

第一行两个整数 n 和 m,用一个空格隔开,分别表示接水人数和龙头个数。

第二行 n 个整数 1,2,…,w1​,w2​,…,wn​,每两个整数之间用一个空格隔开,wi​ 表示 i 号同学的接水量。

输出格式

一个整数,表示接水所需的总时间。

输入输出样例

输入 #1复制

5 3
4 4 1 2 1

输出 #1复制

4

输入 #2复制

8 4
23 71 87 32 70 93 80 76

输出 #2复制

163

说明/提示

【输入输出样例 #1 说明】

第 1 秒,3 人接水。第 1 秒结束时,1,2,3 号同学每人的已接水量为 1,3 号同学接完水,4 号同学接替 3 号同学开始接水。

第 2 秒,3 人接水。第 2 秒结束时,1,2 号同学每人的已接水量为 2,4 号同学的已接水量为 1。

第 3 秒,3 人接水。第 3 秒结束时,1,2 号同学每人的已接水量为 3,4 号同学的已接水量为 2。4 号同学接完水,5 号同学接替 4号同学开始接水。

第 4 秒,3 人接水。第 4 秒结束时,1,2 号同学每人的已接水量为 4,5 号同学的已接水量为 1。1,2,5 号同学接完水,即所有人完成接水的总接水时间为 4 秒。

【数据范围】

1≤n≤10000,1≤m≤100,m≤n;

1≤wi​≤100。

代码

#include
int a[10010];
int main()
{
    int n,m,t=0;
    scanf("%d %d",&n,&m);
    for(int i=0;i

P1294 高手去散步

题目描述

高手最近谈恋爱了。不过是单相思。“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求。今天,这个阳光明媚的早晨,太阳从西边缓缓升起。于是它找到高手,希望在晨读开始之前和高手一起在鳌头山上一起散步。高手当然不会放弃这次梦寐以求的机会,他已经准备好了一切。鳌头山上有 n 个观景点,观景点两两之间有游步道共 m 条。高手的那个它,不喜欢太刺激的过程,因此那些没有路的观景点高手是不会选择去的。另外,她也不喜欢去同一个观景点一次以上。而高手想让他们在一起的路程最长(观景时它不会理高手),已知高手的穿梭机可以让他们在任意一个观景点出发,也在任意一个观景点结束。

输入格式

第一行,两个用空格隔开的整数 n 、m 之后 m 行,为每条游步道的信息:两端观景点编号、长度。

输出格式

一个整数,表示他们最长相伴的路程。

输入输出样例

输入 #1复制

4 6
1 2 10
2 3 20
3 4 30
4 1 40
1 3 50
2 4 60

输出 #1复制

150

说明/提示

对于 100% 的数据:n≤20,m≤50,保证观景点两两之间不会有多条游步道连接。

代码

#include
int max1=0,book[30],n,L[70][70];
void dsf(int spot,int sum)
{
	if(sum>max1)  
	    max1=sum;//更新最大值
	for(int i=1;i<=n;i++)
	{
		if(L[spot][i]>0&&book[i]==0)//判断是否有路,是否已在路径中
		{
			book[i]=1;//标记该点已在路径中
			dsf(i,sum+L[spot][i]); 
			book[i]=0;//取消标记 
		}     
	}
	return;
} 
int main()
{
    int i,j,m,a,b,c,max=0;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	    for(j=1;j<=n;j++) 
			L[i][j]=0;
	for(i=1;i<=m;i++)//输入道路		    
	{
		scanf("%d %d %d",&a,&b,&c);
		L[a][b]=c;
		L[b][a]=c;//无向图
	} 
	for(i=1;i<=m;i++)//模拟从不同景点出发
	{
		book[i]=1;//标记该点已在路径中
		dsf(i,0);
		if(max1>max)
		   max=max1;//更新最大值
		book[i]=0; 
	}
	printf("%d\n",max);
	return 0; 	
}

P1706 全排列问题

题目描述

按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 n。

输出格式

由 1∼n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 5 个场宽。

输入输出样例

输入 #1复制

3

输出 #1复制

    1    2    3
    1    3    2
    2    1    3
    2    3    1
    3    1    2
    3    2    1

说明/提示

1≤n≤9。

代码

#include
int book[20],a[20],n;
void dsf(int step)
{
	int i;
	if(step==n+1)
	{
		for(i=1;i

P1739 表达式括号匹配

题目描述

假设一个表达式有英文字母(小写)、运算符(+-*/)和左右小(圆)括号构成,以 @ 作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则输出 YES;否则输出 NO。表达式长度小于 255,左圆括号少于 20 个。

输入格式

一行:表达式。

输出格式

一行:YES 或 NO

输入输出样例

输入 #1复制

2*(x+y)/(1-x)@

输出 #1复制

YES

输入 #2复制

(25+x)*(a*(a+b+b)@

输出 #2复制

NO

说明/提示

表达式长度小于 255,左圆括号少于 20 个。

注意:)(a+b)(,())(等情况

代码

#include
#include
int main()
{
	char a[300];
	int i,top=0;
	scanf("%s",a);
	for(i=0;;i++)
	{
		if(i==0&&a[i]==')')
		{
			top=-1;
			break;
		}
		if(a[i]=='(')  top++;
		else if(a[i]==')')  top--;
		if(top<0)  break;//‘)’数大于‘(’时,不符合条件,退出循环
		if(a[i]=='@')  break; 
	}
	if(top==0)	printf("YES");
	else printf("NO");
}

P1996 约瑟夫问题

题目描述

n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

输入格式

输入两个整数 n,m。

输出格式

输出一行 n 个整数,按顺序输出每个出圈人的编号。

输入输出样例

输入 #1复制

10 3

输出 #1复制

3 6 9 2 7 1 8 5 10 4

说明/提示

1≤m,n≤100

代码

#include
int main()
{
	int n,m;
	int a[150]={0},b[150]={0};
	int cnt=0;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		a[i]=i;		
	int j=1,k=n;
	while(k>0)
	{
		for(int i=1;i<=n;i++)
		{
    	    if(a[i]!=0)//判断是否出圈
    		cnt++;
		    if(cnt==m)
		    {
			    b[j++]=a[i];
			    a[i]=0;//出圈
			    cnt=0;
			    k--;
	        }
	    }
	}
	for(int i=1;i<=n;i++)
		printf("%d ",b[i]);
}

P2404 自然数的拆分问题

题目描述

任何一个大于 1 的自然数 n,总可以拆分成若干个小于 n 的自然数之和。现在给你一个自然数 n,要求你求出 n 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数 n。

输出格式

输出:若干数的加法式子。

输入输出样例

输入 #1复制

7

输出 #1复制

1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4

说明/提示

数据保证,2≤n≤8。

代码

#include
int a[10],n;
void dsf(int num,int sum,int step)
{
	if(num==n)
	    return;
	if(sum==n)
	{
		for(int i=1;i

你可能感兴趣的:(学习,算法)