P1116 车厢重组

这篇博客探讨了如何利用编程解决实际问题,如火车站车厢排序和硬币翻转。对于车厢排序问题,采用了冒泡排序的思想,计算每个元素在正确位置前需要交换的次数。而对于硬币翻转,通过每次翻转一枚硬币达到目标状态。最后,还介绍了如何计算烟蒂可以换取的烟的数量。这些问题都展示了算法在实际场景中的应用。
摘要由CSDN通过智能技术生成

题目描述

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入格式

共两行。

第一行是车厢总数 N(≤10000)。

第二行是 N个不同的数表示初始的车厢顺序。

输出格式

一个整数,最少的旋转次数。

输入输出样例

输入

4
4 3 2 1 

输出 

6

思路

这道题可以用冒泡排序的方式来做,但是该题目并不求最终输出的序列,只是求一共有多少次,那我们可以求在一个数

前面有多少个比它小的数。有多少个就要换多少次。


代码

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	int a[n],i,j,sum=0;
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(i=0;i<n;i++)
	{
		for(j=0;j<i;j++)
		{
			if(a[j]>a[i])
			sum++;
		}
	}
	printf("%d",sum);
	return 0;
}

P1146 硬币翻转

题目描述

在桌面上有一排硬币,共NN枚,每一枚硬币均为正面朝上。现在要把所有的硬币翻转成反面朝上,规则是每次可翻转任意N-1N−1枚硬币(正面向上的被翻转为反面向上,反之亦然)。求一个最短的操作序列(将每次翻转N-1枚硬币成为一次操作)。

输入格式

一个自然数NN(NN为不大于100100的偶数)。

输出格式

第一行包含一个整数SS,表示最少需要的操作次数。接下来的SS行每行分别表示每次操作后桌上硬币的状态(一行包含NN个整数(00或11),表示每个硬币的状态:00――正面向上,和11――反面向上,不允许出现多余空格)。

对于有多种操作方案的情况,则只需操作的字典序最小输出一种。

注:操作的字典序:对于一次操作,1表示翻转,0表示不反转。

但是需要你输出的是每一次操作完的状态,0表示正面朝上,1表示反面朝上。

输入输出样例

输入 

4

输出 

4
0111
1100
0001
1111


思路

每一次翻转n-1枚硬币,那我们可以逆向思考,每一次就是翻转一枚硬币,通过数学规律我们可以发现,第i次时第i枚硬币不翻转。根据这个思路可以很简单的做出来。

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	int a[n];
	int i;
	for(i=0;i<n;i++)
	{
		a[i]=0;
	}
	int j;
	printf("%d\n",n);
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			if(i!=j)
			{
				if(a[j]==1) a[j]=0;
				else a[j]=1;
			}
			printf("%d",a[j]);
		}
		printf("\n");
	}
	return 0;
}

P1150 Peter 的烟

题目描述

Peter 有 nn 根烟,他每吸完一根烟就把烟蒂保存起来,kk(k>1k>1)个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

输入格式

每组测试数据一行包括两个整数 n, kn,k(1 < n, k≤10^8)。

输出格式

对于每组测试数据,输出一行包括一个整数表示最终烟的根数。

输入输出样例

输入1

4 3

输出 1

5

输入2

10 3

输出 2

14

说明/提示

对于 100% 的数据,1<n, k≤10^8。


思路

1、可以根据数学方法,直接算出最后的结果。

 sum=n+(n-1)/(k-1)

2、我们可以用一个while模拟整个过程

首先我们用m来表示烟头的数量,当烟头的数量大于等于k时,进入循环,可以换取烟头。此时sum要加一,m烟头数量要减去k,换完烟后要加上换得到的那根烟头。直到烟头不足以换取烟为止。

代码

//#include<stdio.h>
//int main()
//{
//	int n,k;
//	scanf("%d %d",&n,&k);
//	int sum=n+(n-1)/(k-1);
//	printf("%d",sum);
//	return 0;
//}

#include<stdio.h>
int main()
{
	int n,k;
	scanf("%d %d",&n,&k);
	int sum=n;
	int m=sum;//m为烟头的数量
	while(m>=k)
	{
		m=m-k;
		sum++;
		m++;
	}
	printf("%d",sum);
	return 0; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值